Categories
Modern JavaScript

Best Features of ES2017 — Async Functions and Arrays and Shared Buffers

Spread the love

Since 2015, JavaScript has improved immensely.

It’s much more pleasant to use it now than ever.

In this article, we’ll look at the best features of ES2017.

Async Functions and Array.prototype.forEach()

Array.prototype.forEach doesn’t work with the async and await syntax.

For instance, if we have:

async function downloadContent(urls) {
  urls.forEach(async url => {
    const content = await makeRequest(url);
    console.log(content);
  });
}

then we won’t get all the results of the promises because forEach doesn’t wait for each promise to finish.

Instead, we want to use the for-of loop to iterate through each async function to get our result:

async function downloadContent(urls) {
  for (const url of urls) {
    const content = await makeRequest(url);
    console.log(content);
  }
}

The for-of loop is aware of the await operator so we can use it loop run all the async functions sequentially.

If we want to run the async functions in parallel, we can use Promise.all :

async function downloadContent(urls) {
  await Promise.all(urls.map(
    async url => {
      const content = await makeRequest(url);
      console.log(content);
    }));
}

We mapped the URLs to async functions so that we can call Promise.all on the array of promises.

And we return a promise with the resolved value being an array of the promises’ resolved values.

Immediately Invoked Async Function Expressions

We can create async functions that are run immediately.

For instance, instead of writing:

async function foo() {
  console.log(await promiseFunc());
}
foo();

We can write:

(async function () {
  console.log(await promiseFunc());
})();

It can also be an arrow function:

(async () => {
  console.log(await promiseFunc());
})();

Unhandled Rejections

We don’t have to worry about unhandled rejections when we use async functions.

This is because browsers report them to us when we encounter them.

For instance, we can write:

async function foo() {
  throw new Error('error');
}
foo();

Then we’ll see the error logged in the console.

Shared Array Buffers

ES2017 introduced shared array buffers which lets us build concurrent apps.

They let us share the bytes of a SharedArrayBuffer object between multiple workers and the main thread.

The buffer us shared and is wrapped in a typed array so we can access them.

We can share data between workers quickly and coordination between workers is simple and fast.

For instance, we can create a shared array buffer by writing:

const worker = new Worker('worker.js');

const sharedBuffer = new SharedArrayBuffer(
  100 * Int32Array.BYTES_PER_ELEMENT);

worker.postMessage({
  sharedBuffer
});

const sharedArray = new Int32Array(sharedBuffer);

We created a worker in worker.js .

Then we created a shared buffer with the SharedArrayBuffer .

It can contain 100 elements.

Then to share the buffer with the worker, we call postMessage to pass the buffer to the worker,.

To access the buffer’s data, we create a new Int32Array instance.

Then in the worker.js worker, we get the buffer by writing:

self.addEventListener('message', (event) => {
  const {
    sharedBuffer
  } = event.data;
  const sharedArray = new Int32Array(sharedBuffer);
  //...
});

We listen to the message event and get the sharedBuffer property of event.data .

Then we can access it the same way.

Conclusion

Async functions don’t work well with existing array instance methods.

Also, we can use shared array buffers to share data between the main and worker threads.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *