The Farrelly logo

It started with a promise

A promise is an object which will return an asynchronous (think not at the same time) result. The classic promise use case is fetching data from a remote server. You have no idea how long it’ll take for the data to come back, you’re just promising JS that it’ll come. You can then access it

new Promise( (resolve, reject) => {
  // logic to resolve or reject}.then(result => {
  // logic with the result of the promise
}

Await (hehe), what if the data never comes back from the server?

Two things. Before the promise resolves or rejects its status is set to be pending. If it returns the data successfully, the status is set to be fulfilled, or rejected if the fetch failed. Secondly, you can handle that scenario using a ‘.catch’

e.g.

new Promise( (resolve, reject) => {
  // ...}.then(result => {
  // ...}.catch((error) => {    // logic with the error}

What’s an example of a promise in use?

Here’s a promise that after a thousand ms, will resolve.

const myPromise = new Promise((resolve, reject) => {
  setTimeout( () => { resolve(‘finished’) }, 1000)
}

Wait, what’s the ‘resolve’ and ‘reject’?

So when you receive a result, you then either ‘resolve’ (fulfill) or ‘reject’ (reject) the promise result. To resolve the promise is for it to be successful, whilst a rejection is for it failing. A rejection is then handled by the catch scenario described above.

When I ‘console.log’ the value ‘myPromise’, I just get this ..

[object Promise] { ... }

How can I use the result?

Well you’re actually just logging the ‘Promise’ not the result, it’s asynchronous remember? To access it’s fulfilled value, you’ll need to use a ‘.then’.

const myPromise = new Promise((resolve, reject) => {
  setTimeout(
    () => { resolve(‘finished’) },
    1000
}.then(result => {    // you have access to the result within this scope}

What about when I need to use that result in another promise?

Let me introduce you to callback hell..

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('finished');
  }, 1000);
}).then((result) => {
  new Promise((res, rej) => {
    setTimeout(() => {
      res('I am glad that I have ' + result);
    }, 1000);
  }).then((r) => {
    console.log('r:', r);
  });
});

console.log(myPromise);
[object Promise] {}

“r:”, “I am glad that I have finished”

Note that we receive an [object Promise… because the Promise is pending, and we’re not in the correct scope to see the result. However, the console log within the Promise is in the correct scope, and can see the result.

There are legitimate scenarios where developers end up in.. callback hell. Imagine thunder striking as those two words are read

How can you avoid it?

Await, on this, there’s new syntax for handling a Promise. ‘Async/Await’

So instead of having to wait for the result of a Promise in order to chain another, you can just wait for it, well I should say, you can ‘await’ it


const fetch = async () => await setTimeout(() => console.log(‘hello’), 1000)
// equivalent to
function async fetch() {
  await setTimeout(() => console.log(‘hello’), 1000)}

You can only await on a function which has been marked as async.

However, there is one prerequisite for the async/await syntax. Await can only be called within an async function. So you’re not able to just slap it’s usage in anywhere, but with that being said, with an inline function (as is in the above code snippet), it’s effectively the same as a promise.

If you remember the callback hell from before, here’s it now

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('finished');
  }, 1000);
}).then((result) => {
  new Promise((res, rej) => {
    setTimeout(() => {
      res('I am glad that I have ' + result);
    }, 1000);
  }).then((r) => {
    console.log('r:', r);
  });
});

console.log(myPromise);
[object Promise] {}

"r:", "I am glad that I have finished"

This way you can now easily await multiple fetches, or requests.

Conclusion

So we’ve learnt :

  • What a promise is, how to use them, how to access them
  • Promise statuses, then, catch
  • Callback hell
  • Async/await syntax

Is there more you want to know about Promises, or Async/Await?

What do you think about the evolution of asynchronous code in JS?