Async函数是Brian Terlson提出的ECMAScript提案,目前处于stage 3(candidate 候选)阶段。
| 译者注:ECMAScript提案分三个阶段:草图(Sketch) -> 提案(Proposal) -> 规范(Standard),所以Async很大的希望能成为规范.
在开始解释async函数之前,我想先讲一下如何通过组合Promises和generators用看起来同步的代码来控制异步操作。
通过 Promises 和 generators 写异步代码
在众多的能用于异步的函数中,Promises,作为ES6的一部分,变得越来越受欢迎。一个例子就是客户端的fetch API,用来发送请求获取数据从而替代XMLHttpRequest。使用fetch看起来像下面这样:
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库通过使用Promises和generators能让代码看起来更同步,上面的例子用co来写就是下面这样子:
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}`);
}
});
fetchJson('http://example.com/some_file.json').then(obj => console.log(obj));
每一次回调(一个generator函数)都会传递一个Promises给到co,然后回调进入暂停状态。一旦Promise执行完毕,co就会触发回调:如果Promise返回fulfilled(成功),yield返回成功状态的值,如果返回rejected(失败),yield就会抛出失败的错误。另外,co会将返回的回调包装成一个Promise(跟then()的用途一样)。
Async 函数
上面的例子用Async函数的基本用法实现如下:
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}`);
}
}
fetchJson('http://example.com/some_file.json').then(obj => console.log(obj));
在实现上,async函数更像generators,但是不会转换成generatos函数.
Internally, async functions work much like generators, but they are not translated to generator functions.
Async 函数其他的一些用法
现在存在如下的async函数的变体:
- Async 函数声明:
async function foo() {} - Async 函数表达式:
const foo = async function() {} - Async 方法定义:
let obj = { async foo() {} } - Async 箭头函数:
const foo = async () => {};
深入阅读
Async Functions(Brian Terlson)
Simplifying asynchronous computations via generators(“Exploring ES6”的章节)
本文对你有帮助?欢迎扫码加入前端学习小组微信群:
