Async 函数
异步编程的最高境界,就是根本不用关系它是不是异步
async 函数如同隧道尽头的光亮,可能是异步操作的终极方案
async 函数是什么
aysnc 函数就是 Generator 函数的语法糖
Generator 函数读取两个文件
var fs = require("fs");
var readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function (error, data) {
if (error) reject(error);
resolve(data);
});
});
};
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 函数优点
async 函数对 Generator 函数的改进体现在以下三点
内置执行器
Generator 函数的执行必须依靠执行器,才有了co 函数库
而 async 函数自带执行器
更好的语义
async await 比起星号和 yield 语义更清楚
async 表示函数里有异步操作 await 表示紧跟在后面的表达式需要等待返回结果
更广泛的适用性
co 函数库约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。
async 函数的用法
async 函数和 Gernerator 函数一样,返回一个 Promise 对象,可以使用 then 方法添加回调函数
当函数执行的时候,遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体后面的语句
async function getStockPriceByName(name) {
var symbol = await getStockSymbol(name);
var stockPrice = await getStockPrice(symbol);
return stockPrice;
}
getStockPriceByName("goog").then(function (result) {
console.log(result);
});
async 函数的实现
async 的实现时将 Generator 函数和自动执行器包装在一个函数里
async function fn(args) {
// ...
}
// 等同于
function fn(args) {
return spawn(function* () {
// ...
});
}
所有的 async 函数都可以写成上面的第二种形式,其中的 spawn 函数就是自动执行器。
下面给出 spawn 函数的实现,基本就是前文自动执行器的翻版。
function spawn(genF) {
return new Promise(function (resolve, reject) {
var gen = genF();
function step(nextF) {
try {
var next = nextF();
} catch (e) {
return reject(e);
}
if (next.done) {
return resolve(next.value);
}
Promise.resolve(next.value).then(
function (v) {
step(function () {
return gen.next(v);
});
},
function (e) {
step(function () {
return gen.throw(e);
});
}
);
}
step(function () {
return gen.next(undefined);
});
});
}
参见