Logo

dev-resources.site

for different kinds of informations.

Promises: The Ability to Write Asynchronous Code Using Javascript

Published at
11/11/2024
Categories
es6
learning
api
Author
evanloria4
Categories
3 categories in total
es6
open
learning
open
api
open
Author
10 person written this
evanloria4
open
Promises: The Ability to Write Asynchronous Code Using Javascript

Introduction

By nature, Javascript is a synchronous, single-threaded programming language. This means that operations are run one at a time, in the order they were called. Web applications need the ability to perform multiple operations at the same time. Using synchronous code, a program would have to wait for an operation to complete before the program could continue running. For this reason, Javascript offers a way for developers to create asynchronous operations that perform in the background, allowing code to continue running before an operation is completed.

Asynchronous Callbacks

A callback is a function that is passed into another function to be called at the appropriate time. Before the introduction of promises in Javascript ES6, callbacks were used to handle asynchronous operations. Because Javascript uses an event loop to track the order in which functions should be executed, functions are able to execute in a different order in which they were called.

const addOne = function(number) {
  number += 1;
  return number;
};
const addNextNumber = function (number, addOne) {
  return number + addOne(number);
}
addNextNumber(5);
Enter fullscreen mode Exit fullscreen mode

The addNextNumber function relies on the return of the addOne function. The addOne function finishes executing, and then the addNextNumber function is able to complete its operation.

However, if we need to pass multiple callbacks into one another our code can become difficult to understand. When callbacks become overly nested it is called callback hell, or the pyramid of doom.

Example From MDN:

function doStep1(init, callback) {
  const result = init + 1;
  callback(result);
}
function doStep2(init, callback) {
  const result = init + 2;
  callback(result);
}
function doStep3(init, callback) {
  const result = init + 3;
  callback(result);
}
function doOperation() {
  doStep1(0, (result1) => {
    doStep2(result1, (result2) => {
      doStep3(result2, (result3) => {
        console.log(`result: ${result3}`);
      });
    });
  });
}
doOperation();
Enter fullscreen mode Exit fullscreen mode

You can see how nesting callbacks can become difficult to read when callback functions take in another callback. Especially when dealing with more complicated callbacks that fetch data from a server.

Promises

A promise is a unique object that is returned by an asynchronous function that represents the eventual success or failure of an asynchronous operation. Promises are the foundation of asynchronous Javascript. Promise objects contain two properties: state and result:

State Property Value Options

  • Pending: The function that created the promise has not finished executing
  • Fulfilled: The asynchronous function succeeded
  • Rejected: The asynchronous function failed

Result Property Value Options

  • The value of the successful result
  • The value of the failed result
  • Undefined

It is worth noting that the above properties are not code-accessible. We can only view them using a debugger tool.

The Fetch API is what javascript uses to make requests to a server. It replaced XMLHttpRequest, which uses callbacks. A request is made by calling fetch(), which can take in an object, or a string url of a resource to send a request to. The return value of fetch() is a promise object.

Promise Handlers

The promise object supplies methods to deal with the result of a promise. We will be talking about the .then() and .catch() handlers, but you can find other promise handlers here.

.then() Handler

.then() takes in two callback arguments: one for the case of a fulfilled promise, and one for the rejected promise. This handler is capable of returning a promise, returning a value, or throwing an error.
Let's set a variable equal to the promise returned by invoking fetch()

const ourPromise = fetch("https://example.com/post");
Enter fullscreen mode Exit fullscreen mode

We can attach then() to our promise, and once the promise is fulfilled or rejected it will perform the corresponding callback argument.

const fulfilledCB = function() {
console.log('Promise was successful');
};
const rejectedCB = function() {
console.log('Promise failed');
};
ourPromise.then(fulfilledCB, rejectedCB); 
Enter fullscreen mode Exit fullscreen mode

If our promise is returned successfully, our fulfilledCB will run. If the promise was rejected, then our rejectedCB will run. We can optionally only pass in a callback for the value we are interested in, setting the unwanted value's callback to null.

Chaining Promises

Once a response object is received using fetch(), we need to use another function to access the data of the response. We can do this using the json() method to transform our promise into a json object.

const ourPromise = fetch("https://example.com/post");
ourPromise.then((response) => {
return response.json();
}).then((user) => {
console.log(user.name)
});
Enter fullscreen mode Exit fullscreen mode

We use our first .then() to transform the promise into json, and the second to access the data within our response object.

.catch()Handler

You may have noticed that in the above code snippet we did not provide a callback to handle rejected promises. When using promise chaining, we attach the .catch handler to the end of our chain. This handler will take in a callback to deal with any promise that was rejected at any point in the chain. .catch() can also be used with only one .then() rather than passing in an error callback to .then().

const ourPromise = fetch("https://example.com/post");
ourPromise.then((response) => {
return response.json();
}).then((user) => {
console.log(user.name)
}).catch(() => {
console.log('One of your promises was rejected');
};
Enter fullscreen mode Exit fullscreen mode

.catch() offers an extremely simple way to handle errors when dealing with asynchronous code.

Conclusion

In order for our programs to run as efficiently as possible, it is imperative that our code have the ability to run asynchronously. Long-running synchronous code would cause a program to become unresponsive while it waited on the return of an operation. Promises offer an elegant solution to writing asynchronous code by improving code readability, simplifying error handling, and allowing developers to avoid callback hell.

Sources:

MDN Promises
MDN Introduction to Asynchronous Code
Free Code Camp Asynchronous Javascript
Green Roots Promises Explained Like I Am Five
Green Roots Handling Promises
Dev Community Callbacks, Promises, and Async/Wait

es6 Article's
30 articles in total
Favicon
Next-Generation Buttons: Implementing the Command Pattern through Web Components
Favicon
Hoisting: facing Temporal dead zone
Favicon
Learn javascript promises. Part 1 β€” What is a promise?
Favicon
Bootcamping 02: Named exports and default exports - does it really matter?
Favicon
Mastering Modern JavaScript: A Deep Dive into ES6 Function Creation and Best Practices
Favicon
Promises: The Ability to Write Asynchronous Code Using Javascript
Favicon
Exploring JavaScript's Modern Primitives: BigInt and Symbol
Favicon
JavaScript ES6 Release Notes: Unleashing the Power of Modern JavaScript
Favicon
WHY YOU SHOULD LEARN ES6
Favicon
Understanding ES6 API's
Favicon
Transpiler vs Polyfills
Favicon
JavaScript Spread Syntax: Expanding Arrays and Objects
Favicon
API Design and Debugging:A Comprehensive Guide for BeginersπŸš€
Favicon
Understanding the JavaScript Spread Operator (With Examples)
Favicon
A Comprehensive Guide to ES6 and Arrow Functions
Favicon
Controla tus promesa con JavaScript
Favicon
Sets
Favicon
Enhanced Object Literals
Favicon
Iteration Stament i.e for-of loop
Favicon
1.1 Ins & outs of ES6(JavaScript) Import with Realworld Example and Demo Project.
Favicon
Math Namespace & BigInt
Favicon
JavaScript - Destructuring Arrays & Objects [Live Doc]
Favicon
ES2015 (ES6) Tips, Tricks, Best Practices, and Code Snippet Examples for Your Day-to-Day Workflow
Favicon
Objects in JavaScript
Favicon
Intro to DSA & Big O Notation
Favicon
Execution Context & Call Stack
Favicon
Asynchronous programming in Javascript - Callbacks, Promises & Async Await
Favicon
Loops in JavaScript !!πŸ“šπŸ”„
Favicon
Array
Favicon
Functions

Featured ones: