Skip to content

Latest commit

 

History

History
191 lines (152 loc) · 4.55 KB

README.md

File metadata and controls

191 lines (152 loc) · 4.55 KB

Build Status

async-await

Demonstrate common async operations with both async.js and ES6 async-await.

Node.js v7.6.0 brings official support for async functions. This is an ES7 feature that allows handling asynchronous operations in a clean way.

Here is an overview of major weapons at our disposal to fight callback hell:

Async Functions

Here is a basic example of an async function:

function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time));
}

async function answer() {
  console.log('Start');
  await sleep(2000);
  console.log('End');
  return 42;
}

var p = answer();
assert(p instanceof Promise);
p.then(result => {
  assert.equal(result, 42);
  console.log('OK');
}).catch(err => console.error(err));

src/sleep.js

It all starts and ends with a promise:

  • await takes a promise and suspends the current script until the promise is fulfilled. Then the script is resumed and await returns the resolved value or throws the reject reason.
  • await can appear only in an async function
  • async function always returns a promise, so one can await it

Note that await does not block the event queue, so node.js can process other events while waiting for the promise.

Promisify

We can easily promisify existing callback APIs using packages like pify.

const assert = require('assert');
const pify = require('pify');
const fs = pify(require('fs'));

async function main() {
  let text = await fs.readFile(__filename, 'utf8');
  assert(/some-token/.test(text));

  try {
    await fs.readFile('no-such-file', 'utf8');
    assert(false, 'should throw');
  } catch (err) {
    assert.equal(err.code, 'ENOENT');
  }
}

src/promisify.js

Common Asynchronous Operations

Waterfall

Execute several operations sequentially, each one taking the result from the previous one.

async

function calc(x, cb) {
  async.waterfall([
    inc.bind(null, x),
    double
  ], cb);
}

async-await

async function calc(x) {
  let r = await inc(x);
  return await double(r);
}

Parallel

Start several operations in parallel and wait all of them to complete.

async

function calc(x, cb) {
  async.parallel([
    inc.bind(null, x),
    double.bind(null, x)
  ], cb);
}

async-await

async function calc(x) {
  return await Promise.all([inc(x), double(x)]);
}

Race

Start several operations in parallel and get the result of the first one to complete.

async

function calc(x, y, cb) {
  async.race([
    inc.bind(null, x),
    double.bind(null, y)
  ], cb);
}

async-await

async function calc(x, y) {
  return await Promise.race([inc(x), double(y)]);
}

Map

Execute the same operation for each array element in parallel.

async

function calc(arr, cb) {
  async.map(arr, inc, cb);
}

async-await

async function calc(arr) {
  return await Promise.all(arr.map(inc));
}

Map Series

Execute the same operation for each array element sequentially.

async

function calc(arr, cb) {
  async.mapSeries(arr, inc, cb);
}

async-await

async function calc(arr) {
  return await bluebird.mapSeries(arr, inc);
}

See Also

6 Reasons Why JavaScript’s Async/Await Blows Promises Away

While it compares async functions to promises, the same issues are valid also with callbacks.