Async/await – how it works?

Async/await is a new method of handling asynchronous calls in JavaScript

bookmark

Async/await – how it works?
JavaScript async/await is a new way to deal with asynchronous operations in JavaScript. It offers you the power to make your code shorter and clearer.

Before async/await, callbacks and promises were used to handle asynchronous calls in JavaScript. Everybody who uses JavaScript has heard of the so-called callback hell. Nevertheless, we will not be writing about this since callbacks are not the major focus of this article.

const requestMock = () => new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({
          data: {
            msg: 'success',
            arr: [1,2,3,4,5,6]
          },
          code: "200"
        });
      }, 1 * 1000);
    }); 
(() => {
      requestMock()
        .then(res => res.data.arr)
        .then(arr => {
          if(arr.data.length) {
            return requestMock()
              .then(nextArr => {
                return nextArr.map(nextEl => nextEl+5)
              })
            } else {
              return arr.map(el => el+2)
            }
          }
        })
        .then(arr => console.log(arr));
    })(); 

As you can see in the case above, I want to make a requestMock function on the stub to call an asynchronous operation. It is a perfect illustration of using setTimeout to make a long-running process asynchronous operation.

The promise object – that can be returned from requestMock – uses the then method. This method provides you the option to deal with the asynchronous execution, in case that requestMock ends successfully.

It is worth mentioning that the promise uses not just the then method but also the catch method. The catch method allows you to deal with the asynchronous operations which end unsuccessfully.

You will have to use requestMock() with the ‘then’ method to handle with your asynchronous operations.

Reasons to choose DevsData LLC

a players

Only A-players. Google level engineers

security

Serious about security and sensitive data

meteroic app

Meteoric pace of development with the very recent frameworks

Rewrite a promise to Async/Await

(async () => {
      try {
        let data = [];
        const arr = await requestMock();
        if(arr.data.length) {
          const nextArr = await requestMock();
          data = nextArr.map(nextEl => nextEl+5)
        } else {
          data = arr.map(el => el+2)
        }
        console.log(data);
      } catch (err) {
        console.log(err);
      }
    })(); 

As you can see, in the case above I have used the async keyword, which usually means that this function is asynchronous and returns the promise. At any time you use async/await, make sure you are using the try/catch statement to handle errors.

You also ought to use await to wait for the end of requestMock and declare res to save the returned value. ‘Await’ has to be called inside async. Without await, the asynchronous function will end and it won’t wait for the effect of the asynchronous function.

There are many errors that might occur when dealing with async/await, be sure to watch the video on top to get a head start.

Key points to remember

The two async/await along with the promise play the identical role, but in the first case, use the ‘then’ syntax, whereas at the second case use the async/await syntax. Async/await is much more readable and more comfortable to compose. Async/await is – such as promise – non-blocking.

If you make the decision to use async/await, it is good practice to use tryCatch to handle errors. Together with promise, you need to use only catch to deal with an error. Be cautious! It’s easy to get lost using a promise when you’ve got a lot of nesting (6 levels) bracers and the statements are all returned.

With async/await you won’t have this issue. When you declare async, you may use the await keyword to make your code in a synchronous fashion. The code will appear very similar to its synchronous counterpart, but it is going to be asynchronous.

However, the significant truth is you will still need promises to compose asynchronous code.

Your project MVP in 45 days

During development, we will focus on essential areas and functionalities, taking engineering shortcuts to deliver maximum business value tailored to your goal, be it investor meetings, marketing launch, fundraising, or internal demonstration. For startups that we work with on MVP, we strive to help them find funding for future development, past MVP stage, by leveraging our network of angel investors and VCs from both the US and EU.

Async/await with promises

As we have previously said, an async function returns a promise. So you can write something like that:

const makeRequest = async () => {
     try {
        const res = await requestMock();
        return res.data.arr.map(test => test + 2);
      } catch (err) {
        console.log(err)
      }
    } 
    makeRequest().then(res => {
      // do something 
    }) 

Therefore, you could combine the promise.all and async/await to create a lot of requests:

const makeRequest = async () => {
     try {
        const res = await requestMock();
        return res.data.arr.map(test => test + 2);
      } catch (err) {
        console.log(err)
      }
    } 
    const multipleRequest = async () => {
      await makreRequest() // It is not obligatory to declare the value. We can use the same function.
      const [req1, res1, req3] = await Promise.all([makeRequest, makeRequest, makeRequest])
      console.log([…req1, …req2, …req3 ])
    } 

Let us imagine you need to limit asynchronous operations in time. We typically use the async library to perform it. One of the functions in this library is mapLimit.

MapLimit provides you the opportunity to conduct asynchronous operations if you want to do a few operations at the same time however not all of them at once.

const mapLimit = async (arr, perChunk) => {
      const promiseArr = arr.reduce((all,one,i) => {
        const ch = Math.floor(i/perChunk); 
        all[ch] = [].concat((all[ch]||[]),one); 
        return all
      }, [])
      for (const promise of promiseArr) {
        await Promise.all(promise.map(func => func()))
        console.log('done!');
      }
      return 'Success!!'
    }
    const promiseArr = [request, request, request, request, request, request, request, request, request, request, request, request]
    (async () => {
      try {
        const limit = 3;
        await mapLimit(promiseArr, limit);
      } catch (err) {
          console.log(err)
      }
    })();
    // or …
    // ;(() => {
    //   mapLimit(datadad, 3).then(console.log).catch(console.error)
    // })() 

From the case above, it is possible to observe a standard request function to stub the very long background process. At this point, you are able to create the mapLimit function. In the mapLimit function, you are able to slice up an array of functions into a chunk array.

Then, you may use the for-of loop that was added in ES6 to get the elements of this array.

In the loop, it is helpful to use await Promise.all since you would like to process the requests simultaneously. That is possible because in the beginning of the function, the main array is divided into arrays of chunks functions.

Congratulations! At this point, you have the generic mapLimit function. You can use it every single time you need to process anything simultaneously!

Check out our Portfolio and learn more about the technologies we use

The way to implement async/await with streams

NNode.js 10 was released on April 24, 2018. The publication of Node.js 10 has been a sort of breakthrough since this version permits you to use async/await, when you operate on streams.

Additionally, it is worth mentioning the ES2018 version allows the chance to perform an asynchronous iteration.

Normally, your streams look like this:


    const main = inputFile => {
      const readStream = fs.createReadStream(inputFile, { encoding: 'utf8' });
      readStream.on('data', (line) => {
        console.log(line);
      });
      readStream.on('end', () => {
        console.log('SUCCESS!!');
      });
    } 

Node.js 10 gives you the chance to use an asynchronous iteration to read a file asynchronously. You can iterate streams only in the event that you declare async before the function. More examples are to be found on this page: 2ality.com

 const main = async inputFile => {
      const readStream = fs.createReadStream(inputFile, { encoding: 'utf8' });
      for await (const line of readStream) {
        console.log(line);
      }
      console.log('SUCCESS!!');
    } 

You see? Everything is readable and comprehensible. In this instance, we used the for-await-of loop to iterate. This operation is possible thanks to the Symbol.asyncIterator.

Ready to get started?

phone Schedule a call

To begin, let us take a look at Symbol.iterator

‘Async Iterators` are pretty similar to regular iterators because they implement 3 methods: the next method moves to the next item (the remaining part of the bullet list) and finally a return or a throw method.

There are some discrepancies between an ‘async iterator’ and a traditional ‘iterator’. Rather than returning a plain object { value, done }, an async iterator returns a promise which is the counterpart of { value, done }.

In the same way, an async iterable is an object with a Symbol.asyncIterator function that returns an asynchronous iterator. It allows you to alter the syntax of ‘for…of’ to an asynchronous for await…of.

All these are implemented in current versions of Node.js, and also you can use them by using the – harmony-async-iteration flag.

Summary

You can write code both in an asynchronous fashion and an instinctive manner. Async/await is a syntax that was added in ES8 (ECMAScript 2017) of the JavaScript version. It is supported by all browsers. Node.js developers can use this syntax from the Node.js 8 version.

As you can see, the async/await syntax is not that complex. Are you still asking yourself the question “Async/await – how exactly does it work?”. Do not worry.

It is merely one more method of coping with the promise object, and thanks to this you are now able to write code a whole lot more synchronously and intuitively. It is also important to keep in mind that the ‘Async’ function returns a promise but ‘await’ can only be used within the async.

Lastly, do not forget that you are not left alone with your doubts — if you find something unclear, seek answers on portals for developers, for example Github! Also, feel free to reach us at DevsData anytime.

virtual assistanceF.A.Q.

DevsData – a premium technology partner

DevsData is a boutique software and recruitment agency. Get your software project done by Google-level engineers or scale up an in-house tech team with developers with experience relevant to your industry.

Free consultation with a software expert

Contact Us

DevsData LLC is truly exceptional – their backend developers are some of the best I’ve ever worked with.”

Nicholas Johnson

MENTOR AT YC,
SERIAL ENTREPRENEUR

Got a project idea?

Let's have a call to:

Trending guides for corporate managers and founders


Most in-demand talent 



Got a project idea?

Schedule a call with a software expert

Quote mark

Best back-end engineers I've ever worked with.​

“I interviewed about a dozen different firms. DevsData LLC is truly exceptional – their backend developers are some of the best I’ve ever worked with. I’ve worked with a lot of very well-qualified developers, locally in San Francisco, and remotely, so that is not a compliment I offer lightly. Their depth of knowledge and their ability to get things done quickly."

Nicholas Johnson

CEO OF ORANGE CHARGER LLC;

MENTOR AT YCOMBINATOR

Success

Thank you


We'll get back to you within 1 business day.