async/await是在 ECMAScript 2017定义的,而Node 7.6开始正式支持aync/await,现在LTS版本是8.x,以下不做说明都是在此环境。
async
async有三种定义方式。
async function
先看一个定义async function的例子:
function resolveAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, 2000);
});
}
async function asyncCall() {
console.log('calling');
var result = await resolveAfter2Seconds();
console.log(result);
// expected output: "resolved"
}
asyncCall();
如上定义了一个名为asyncCall的async function。当async被调用的时候,返回Promise,执行完毕,要么resolve一个值,要么 reject一个错误。之所以添加 await是为了等待Promise的执行结果,然后再只想async函数内剩余的部分,这才会输出’resolved’。
async function expression
有了上面的经验,我们来看表达式的定义方式:
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
};
var add = async function(x) { // async function expression assigned to a variable
var a = await resolveAfter2Seconds(20);
var b = await resolveAfter2Seconds(30);
return x + a + b;
};
add(10).then(v => {
console.log(v); // prints 60 after 4 seconds.
});
和 async function类似,这里只不过是把function付给了一个变量。注意最后输出是要延迟4秒,因为使用了 await后是顺序同步执行的。如果按下面的写法,输出则延迟2秒:
var add = async function(x) { // async function expression assigned to a variable
var a = resolveAfter2Seconds(20);
var b = resolveAfter2Seconds(30);
return x + await a + await b;
};
AsyncFunction对象
使用AsyncFunction构造函数也可以声明一个async function,不过应该很少会直接这么用。
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor
var a = new AsyncFunction('a',
'b',
'return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);');
a(10, 20).then(v => {
console.log(v); // prints 30 after 4 seconds
});
await
await 是为async而生:只能出现在async函数体内,用于等待 Promise。
Promise
前面出现的Promise是javascript中用于异步编程的一种方案,这里简单的介绍下基本概念。
Promise对象代表一个异步操作的最终状态(成功或失败),以及相应状态下的结果。
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
console.log(promise1);
它的定义:new Promise( /* executor */ function(resolve, reject) { ... } );
, executor 会立即执行,resolve和reject函数只会执行其中之一。
const myFirstPromise = new Promise((resolve, reject) => {
// do something asynchronous which eventually calls either:
//
// resolve(someValue); // fulfilled
// or
// reject("failure reason"); // rejected
});
简单的说,如果一切顺利就resolve结果,不然就reject一个reason。
结合Promise,和上述async/await,个人理解async/await类似对Promise的语法糖。通过对异步函数的控制,实现顺序执行的控制流。
参考资料
牢记这些基本概念,夯实基础,bug就没有那么容易错过。
Comments