Promises and async functions

With JavaScript, some operations are asynchronous, and many of these asynchronous operations are signalled via promises.

For instance, fetching data from an API is an asynchronous operation; you need to wait until data from the API has been fully down…

With JavaScript, some operations are asynchronous, and many of these asynchronous operations are signalled via promises.

For instance, fetching data from an API is an asynchronous operation; you need to wait until data from the API has been fully downloaded. So, invoking fetch doesn’t give you the data. Instead, it gives you a promise, from which you will need to have another function be called to receive said value, as the first parameter of that function.

With a promise, to get the result the instance that is available, you invoke the then method, and pass in said function as the first parameter.

Here’s an example:

const fetchPromise = fetch('http://example.com/some-api/');


fetchPromise.then(response => {
  // Do something with `response` here.
  //
  // Note: the `response` object doesn't actually contain the data. You will
  // need to invoke either `response.text()` to extract the data into a string
  // object, or `response.json()` to extract the data into an object, if the
  // incoming data is valid JSON.
});

With fetch, we have access to a response object.

But from the response object, we will need to extract the value. And that is done via invoking either response.text(), or response.json(). Both of these methods will yield a promise!

So here’s what the above code would look like if we wanted to extract the textual value of the response.

const fetchPromise = fetch('https://example.com/some-api/');


fetchPromise.then(response => {
  const textPromise = response.text()

  textPromise.then(value => {
    // The paramter `value` will be the extracted string.
  });
});

But it gets better.

You know how in arrays, there’s a flatMap function, and it can accept as return value another array?

The then method in promises acts like flatMap, where you can return another promise, from the callback function in then.

So, to extract the text value, you can invoke the above function like so:

const fetchPromise = fetch('https://example.com/some-api/');


fetchPromise.then(response => {
  const textPromise = response.text();

  return textPromise;
});

Above, we merely returned the promise. But how do we extract the value?

Before going into that, also note this important fact: the then method will always return a promise!

And that promise will—at a high level—be exactly equal to what is returned by the callback in the then.

So, to extract the text, the above code would look like so:

const fetchPromise = fetch('https://example.com/some-api/');


fetchPromise.then(response => {
  const textPromise = response.text();

  return textPromise;
}).then(text => {
  // The value will be in `text`
});

Since we’ve established where promises typically come from, let’s shorten the above code.

fetch('https://example.com/some-api/')
  .then(response => response.text())
  .then(text => {
    // The value will be in `text`
  });

Let’s say the above API yields a string, and we can use that string to invoke another API call. Let’s do that.

We can have numerous ways to do that.

We can nest the invocations.

fetch('https://example.com/some-api/')
  .then(response => {
    return response.text()
      .then(text => {
        return fetch(`https://example.com/some-api/{text}`)
          .then(response => response.text());
      });
  })
  .then(text => {
    // The value will be in `text`
  });

We can nest some of the invocations. Perhaps to group the “response-to-text extraction” logic.

fetch('https://example.com/some-api/')
  .then(response => response.text())
  .then(text => {
    return fetch(`https://example.com/some-api/${text}`)
      .then(response => response.text());
  })
  .then(text => {
    // The value will be in `text`
  });

Or have everything be sequential.

fetch('https://example.com/some-api')
  .then(response => response.text())
  .then(text => {
    return fetch(`https://example.com/some-api/${text}`)
  })
  .then(response => response.text())
  .then(text => {
    // The value will be in `text`
  });



Async functions

OK, the above invocation of then is cumbersome, in many situations. So, a solution to limit the number of then invocations would be to use an async function.

An async function looks like this:

async function something() {
  return 42;
}

An async function doesn’t merely return anything. It only returns a promise!

So, invoking something() will yield a promise.

something()
  .then((value) => {
    console.log(value); // should print 42
  });

It gets even better. An async function allows you to resolve promises without invoking then. You would use the await keyword for that.

So, for instance, if fetch were to be invoked inside an async function, it would look like so:

async function doSomething() {
  const response = await fetch('https://example.com/some-api');
  return response.text();
}

Since async functions return a promise, we can have the above fetch invocations simplified to this:

fetch('https://example.com/some-api')
  .then(async response => {
    const text = await response.text();
    const response2 =
      await fetch(`https://example.com/some-api/${text}`);
    return response2.text();
  });

I don’t know about you, but I’m not a fan of superfluous response variables. A solution is to use then to avoid creating those variables.

fetch('https://example.com/some-api')
  .then(async response => {
    const text = await response.text();
    return fetch(`https://example.com/some-api/${text}`)
      .then(response => response.text());
  });

Print Share Comment Cite Upload Translate
APA
Sal Rahman | Sciencx (2024-03-29T10:37:24+00:00) » Promises and async functions. Retrieved from https://www.scien.cx/2021/08/05/promises-and-async-functions/.
MLA
" » Promises and async functions." Sal Rahman | Sciencx - Thursday August 5, 2021, https://www.scien.cx/2021/08/05/promises-and-async-functions/
HARVARD
Sal Rahman | Sciencx Thursday August 5, 2021 » Promises and async functions., viewed 2024-03-29T10:37:24+00:00,<https://www.scien.cx/2021/08/05/promises-and-async-functions/>
VANCOUVER
Sal Rahman | Sciencx - » Promises and async functions. [Internet]. [Accessed 2024-03-29T10:37:24+00:00]. Available from: https://www.scien.cx/2021/08/05/promises-and-async-functions/
CHICAGO
" » Promises and async functions." Sal Rahman | Sciencx - Accessed 2024-03-29T10:37:24+00:00. https://www.scien.cx/2021/08/05/promises-and-async-functions/
IEEE
" » Promises and async functions." Sal Rahman | Sciencx [Online]. Available: https://www.scien.cx/2021/08/05/promises-and-async-functions/. [Accessed: 2024-03-29T10:37:24+00:00]
rf:citation
» Promises and async functions | Sal Rahman | Sciencx | https://www.scien.cx/2021/08/05/promises-and-async-functions/ | 2024-03-29T10:37:24+00:00
https://github.com/addpipe/simple-recorderjs-demo