Skip to content

async Function Support #1386

Closed
Closed
@aearly

Description

@aearly

One of the elephants in the room is the new async/await support that has come to Node and Chrome, and will soon hit every other major browser. I've been thinking about what Async can do in the async/await world.

Currently, we can adapt async functions by wrapping them with asyncify. Since an async function is essentially just a function that returns a Promise, that old adapter can easily convert it to a callback-style function. However, it leads to the somewhat absurd looking:

async.mapLimit(arr, 10, async.asyncify(async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
}), done);

However, one of the features in the spec for async functions is that:

Object.getPrototypeOf(asyncFn)[Symbol.toStringTag] === "AsyncFunction"

This gives a way to easily detect (native) async functions. We could use this technique to automatically asyncify them. The example above becomes:

async.mapLimit(arr, 10, async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
}, done);

...which seems to flow much more naturally. I also think we should continue to use callbacks. If a user wanted to await the result, they would have to promisify the function, or pify Async as a whole:

let result = await pify(async.mapLimit)(arr, 10, async (val) => {
  let foo = await doSomething(val);
  //...
 return bar;
});

The above method for detecting async functions only works with native functions. I don't think there is a way to detect Babel transpiled functions. We certainly can't detect normal functions that simply return Promises, because we'd have to retroactively not pass a callback. There would he a huge caveat that this would only work without a transpiler in very modern environments, otherwise you still have to manually wrap with asyncify.

Also, admittedly, many Async methods don't make sense with async/await. Most of the control flow methods (save for things like auto and queue) are more easily replicated with native control flow constructs. map and parallel can be replaced with Promise.map and Promise.all. However, the limiting collection functions would be very useful, as well as auto and a few others. (Also, autoInject with async functions is a async control flow dream!)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions