ES proposal: async functions
Async functions are an ECMAScript proposal by Brian Terlson. It is at stage 3 (candidate).
Before I can explain async functions, I need to explain how Promises and generators can be combined to perform asynchronous operations via synchronous-looking code.
Writing async code via Promises and generators
For functions that compute their one-off results asynchronously, Promises, which are part of ES6, are becoming increasingly popular. One example is the client-side fetch
API, which is an alternative to XMLHttpRequest for retrieving files. Using it looks as follows:
function fetchJson(url) {
return fetch(url)
.then(request => request.text())
.then(text => {
return JSON.parse(text);
})
.catch(error => {
console.log(`ERROR: ${error.stack}`);
});
}
fetchJson('http://example.com/some_file.json')
.then(obj => console.log(obj));
co is a library that uses Promises and generators to enable a coding style that looks more synchronous, but works the same as the style used in the previous example:
const fetchJson = co.wrap(function* (url) {
try {
let request = yield fetch(url);
let text = yield request.text();
return JSON.parse(text);
}
catch (error) {
console.log(`ERROR: ${error.stack}`);
}
});
Every time the callback (a generator function!) yields a Promise to co, the callback gets suspended. Once the Promise is settled, co resumes the callback: if the Promise was fulfilled, yield
returns the fulfillment value, if it was rejected, yield
throws the rejection error. Additionally, co promisifies the result returned by the callback (similarly to how then()
does it).
Async functions
Async functions are basically dedicated syntax for what co does:
async function fetchJson(url) {
try {
let request = await fetch(url);
let text = await request.text();
return JSON.parse(text);
}
catch (error) {
console.log(`ERROR: ${error.stack}`);
}
}
Internally, async functions work much like generators, but they are not translated to generator functions.
Variants
The following variants of async functions exist:
- Async function declarations:
async function foo() {}
- Async function expressions:
const foo = async function () {};
- Async method definitions:
let obj = { async foo() {} }
- Async arrow functions:
const foo = async () => {};
Further reading
- Async Functions (Brian Terlson)
- Simplifying asynchronous computations via generators (section in “Exploring ES6”)
Comments
Post a Comment