Skip to content

Instantly share code, notes, and snippets.

@frankstepanski
Last active January 30, 2021 02:06
Show Gist options
  • Save frankstepanski/dd6aa5e746349f34f8ac529970599fbe to your computer and use it in GitHub Desktop.
Save frankstepanski/dd6aa5e746349f34f8ac529970599fbe to your computer and use it in GitHub Desktop.
Understanding the syntax of a promise

Promises

A promise is a type of object that typically wraps around asynchronous code. Promises won't run this code until needed, and they provide methods to extract the final result.

Promises are an ingenious solution. They allow you to wrap your asynchronous code inside an object, and then they provide you with some tools so that you can respond to the asynchronous code when you want to.

To manage asynchronous code, promises have three states:

  • Pending: When a promise is first created, it has a status of pending. For example, with setTimeout(), the pending status would apply to the time that it takes for setTimeout() to be run.
  • Fulfilled: When the promise has finished running, it has a status of fulfilled. This means that it is ready to pass back a value. In the setTimeout() example, this is after the given number of milliseconds have been run.
  • Rejected: If something goes wrong, the promise changes to a status of rejected. This means that something failed. The setTimeout() function doesn't really apply here, but the rejected status is especially likely to come up when you're making external web requests.

Syntax

The code below demonstrates the creation of a promise.

const promise = new Promise((resolve, reject) => {
    // your code
});

The code demonstrates:

  • A new promise can be created using the new keyword with the Promise class. This will create an instance of a promise.
  • Promises can be assigned to variables.
  • The only argument to pass in to the Promise constructor is a callback function that has two parameters: resolve and reject.

Now, take a look at the code below, which wraps setTimeout() in a promise.

const promise = new Promise((resolve) => {
  setTimeout(() => {
    const fortune = "A friend is a present you give yourself.";
    resolve(`Your fortune is: ${fortune}`);
  }, 2500);
});

In the code above, you can see that resolve() is a function. You place the final value that you want to extract from the promise in the resolve() function. In the example above, the final fortune has been placed in resolve().

The reject() function works the same way, except that it is for when the asynchronous code has failed or gone wrong in some way.

Extracting values

When a promise is created, the asynchronous operation inside will attempt to be fulfilled as quickly as possible. However, even after the operation has finished, the value stored inside cannot be accessed.

Thankfully, JavaScript's Promise object offers two methods—then() and catch()—that allow you to pull values out of fulfilled or rejected promises.

The then() method

The then() method can be called on a promise whenever you are ready to receive its value, as long as that value is fulfilled, not rejected. This method usually takes a single argument: a callback function. Inside of that function, you can access the value. Here's an example:

const promise = welcome();
promise.then((result) => {
    console.log('The result is: ', result);
});

The callback has a single parameter, which contains the end result of the promise code.

The code above can also be written to chain directly from the promise, like so:

welcome().then((result) => {
   console.log('The result is: ', result);
});

Because console.log() is a function, you can also just pass it in to then() if you do not need to do anything extra.

welcome().then(console.log);

Remember, it's asynchronous!

Now that you've seen how to access the result of a promise, it can be tempting to do something like this:

let myString = 'The result is: ';
const promise = welcome();
promise.then((result) => {
   myString += result;
});

console.log(myString);

But can you guess what the output of the code above will be? Remember, promises are asynchronous!

The code above will result in the following output:

//> The result is:

When the console.log() function is called, the promise has yet to be completed. It's important to remember that all work on the result of the promise must be done inside of the then() callback function.

The catch() method

Earlier, the then() method was described as a way to extract resolved values. That's because if a value inside of a promise is rejected with the reject() function, it will skip the then() method until it finds a catch().

For example, if no question is provided to the tell() function below, an error message will be passed into the reject() function.

tell()
   .then((result) => {
       console.log('Success:', result);
})
   .catch((error) => {
       console.log("Failure:", error);
});

In the above code, the tell() function has no question passed into it. Therefore, inside the tell() function, the reject() function is called with an error message.

When a promise'ss state changes to rejected, it skips ahead of any then() methods to the next catch() method. Notice that there is only one value logged. The 'Success:' message does not get called at all!

Chain then() and catch()

You can continue to chain then() and catch() statements, depending on what you want to accomplish with the return result. It's important to note that if a then() or catch() doesn't return a promise, it will always move to the next then().

welcome()
   .then(console.log)
   .then(() =>{
       goodbye().then(console.log);
    });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment