异步函数
异步函数,也称为 “async/await” (语法关键字,即 Promise 语法糖),是 ES6 期约模式在 ECMAScript 函数中的应用。async/await 是 ES8 规范新增的。这个特性从行为和语法上都增强了 JavaScript,让以同步方式写的代码能够异步执行。
/**
* Promise ES6语法在一定程度上是复杂的,如果需要获取解决值,则必须写入处理程序
* 如下代码演示:
*/
const p = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'success');
});
p.then(value => console.log(value));
// 1s后打印 success
/**
* 改进一下,提前定义处理程序
*/
function resolveHandler(value) {
console.log(value);
}
p.then(resolveHandler);
这个改进其实也不大。这是因为任何需要访问这个期约所产生值的代码,都需要以处理程序的形式来接收这个值。也就是说,代码照样还是要放到处理程序里。ES8 为此提供了 async/await 关键字。
异步函数
ES8 的 async/await 旨在解决利用异步结构组织代码的问题。为此,ECMAScript 对函数进行了扩展,为其增加了两个新关键字:async
和 await
。
async
async
关键字用于声明异步函数。这个关键字可以用在函数声明、函数表达式、箭头函数和类方法上:
async function name() {}
let name2 = async function () {};
let name3 = async () => {};
class People {
async getName() {}
}
异步函数如果使用 return 关键字返回了值(如果没有 return 则会返回 undefined),这个值会被 Promise.resolve()包装成一个期约对象。异步函数始终返回期约对象。在函数外部调用这个函数可以得到它返回的期约:
async function foo() {
return 'success';
/**
* 直接返回一个期约对象也是一样的
* return Promise.resolve("success")
*/
}
// 给返回的期约添加一个解决处理程序
foo().then(console.log); // success
异步函数的返回值期待(但实际上并不要求)一个实现 thenable 接口的对象,但常规的值也可以。如果返回的是实现 thenable 接口的对象,则这个对象可以由提供给 then()的处理程序“解包”。如果不是,则返回值就被当作已经解决的期约。下面的代码演示了这些情况:
/*返回一个原始值*/
async function fn1() {
return 'fn1';
}
fn1().then(console.log); // fn1
/*返回一个没有实现 thenable 接口的对象*/
async function fn2() {
return ['fn2'];
}
fn2().then(console.log); // ['fn2']
/*返回一个没有实现 thenable 接口的对象*/
async function fn3() {
const thenable = {
then(callback) {
callback('fn3');
},
};
return thenable;
}
fn3().then(console.log); // fn3
/*返回一个期约*/
async function fn4() {
return Promise.resolve('fn4');
}
fn4().then(console.log); // fn4