ES2017 标准引入了 async 函数,使得异步操作变得更加方便。 async 函数是什么?一句话,它就是 Generator 函数的语法糖。
var fs = require('fs');
var readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function(error, data) {
if (error) return reject(error);
resolve(data);
});
});
};
//generator写法
var gen = function* () {
var f1 = yield readFile('/etc/fstab');
var f2 = yield readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
写成 async 函数,就是下面这样。
var asyncReadFile = async function () {
var f1 = await readFile('/etc/fstab');
var f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
一比较就会发现, async 函数就是将 Generator 函数的星号( * )替换 成 async ,将 yield 替换成 await ,仅此而已。
async 表示函数里有 异步操作, await 表示紧跟在后面的表达式需要等待结果。async 函数的返回值是 Promise 对象,你可以用 then 方法指定下一步的操作。
async function getStockPriceByName(name) {
var symbol = await getStockSymbol(name);
var stockPrice = await getStockPrice(symbol);
return stockPrice;
}
getStockPriceByName('goog').then(function (result) {
console.log(result);
});
正常情况下, await 命令后面是一个 Promise 对象。如果不是,会被转成一个立 即 resolve 的 Promise 对象。
async function f() {
return await 123;
}f().then(v => console.log(v))
// 123
有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以 将第一个 await 放在 try…catch 结构里面,这样不管这个异步操作是否成 功,第二个 await 都会执行。
async function f() {
try {
await Promise.reject('出错了');
} catch(e) { }
return await Promise.resolve('hello world');
}
f() .then(v => console.log(v)) // hello world