异步函数,也称为“async/await”(语法关键字),是 ES6 Promise
模式在 ECMAScript 函数中的应用。
async/await 是 ES8 规范新增的。这个特性从行为和语法上都增强了 JavaScript,让以同步方式写的代码能够异步执行。
下面来看一个最简单的例子,这个 Promise
在超时之后会处理为一个值:
let p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 3));
这个 Promise
在 1000 毫秒之后处理为数值 3。如果程序中的其他代码要在这个值可用时
访问它,则需要写一个解决处理程序:
let p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 3));
p.then((x) => console.log(x)); // 3
这其实是很不方便的,因为其他代码都必须放到 Promise
处理程序中。不过可以把处理程序定义为一个函数:
function handler(x) { console.log(x); }
let p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 3));
p.then(handler); // 3
这个改进其实也不大。这是因为任何需要访问这个 Promise
所产生值的代码,都需要以处理程序的形式来接收这个值。也就是说,代码照样还是要放到处理程序里。
ES8 为此提供了 async/await
关键字
声明一个异步函数可以用在所有函数声明方式中
// 函数声明中
async function foo() {}
// 函数表达式中
let bar = async function() {};
// 箭头函数中
let baz = async () => {};
// 类里的方法
class Person {
async sleep() {}
}
使用 async 关键字可以让函数具有异步特征,但总体上其代码仍然是同步求值的。而在参数或闭包方面,异步函数仍然具有普通 JavaScript 函数的正常行为。正如下面的例子所示, foo() 函数仍然会在后面的指令之前被求值
async function foo() {
console.log(1);
}
foo();
console.log(2);
// 1
// 2
不过,异步函数如果使用 return 关键字返回了值(如果没有 return 则会返回 undefined ),这个值会被 Promise.resolve() 包装成一个期约对象。异步函数始终返回Promise对象。在函数外部调用这个函数可以得到它返回的Promise:
async function foo() {
console.log(1);
return 3;
}
// 给返回的Promise添加一个解决处理程序
foo().then(console.log);
console.log(2);
// 1
// 2
// 3
当然,直接返回一个Promise对象也是一样的:
async function foo() {
console.log(1);
return Promise.resolve(3);
}
// 给返回的Promise添加一个解决处理程序
foo().then(console.log);
console.log(2);
// 1
// 2
// 3
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。