《深入理解ES6》阅读随笔
在使用 JavaScript 写程序的过程中,会遇到一些异步调用的情况,如果只是单层的异步调用,还比较好理解,但如果是多重循环嵌套,那么处理起来就会比较棘手。在 ES6 中,可以利用生成器的 yield 暂停功能,来处理一些异步任务。
简单的任务执行器
run1 定义了一个简单的任务执行器,将需要异步执行的任务放在生成器中传给 run1,即可实现简单的异步执行功能:
// 简单的任务执行器
function run1(task) {
let tasker = task(); // 实例化迭代器
let result = tasker.next();
function step() {
if (!result.done) {
console.log("setp:", result.value);
result = tasker.next();
step();
}
}
step();
}
console.log("----- 简单的任务执行器 -----");
run1(function* () {
yield 1;
yield 2;
});
// 输出结果:
// ----- 简单的任务执行器 -----
// setp: 1
// setp: 2
向任务执行器传递参数
run2 跟 run1 类似,多了传参的功能:
// 向任务执行器传递参数
function run2(task) {
let tasker = task();
let result = tasker.next();
function step() {
if (!result.done) {
console.log("setp:", result.value);
result = tasker.next(result.value);
step();
}
}
step();
}
console.log("----- 向任务执行器传递参数 -----");
run2(function* () {
let first = yield 1;
yield first + 2;
});
// 输出结果:
// ----- 向任务执行器传递参数 -----
// setp: 1
// setp: 3
异步任务执行器
run3 比 run2 更进一步,将传递的参数换为函数,可以用于处理异步函数:
// 异步任务执行器
function run3(task) {
let tasker = task();
let result = tasker.next();
function step() {
if (!result.done) {
// 判断参数是否为函数
if (typeof result.value === "function") {
result.value(function (err, data) {
if (err) {
result = tasker.throw(err);
return;
}
result = tasker.next(data);
step();
});
} else {
result = tasker.next(result.value);
step();
}
}
}
step();
}
console.log("----- 异步任务执行器 -----");
const fs = require("fs");
function readfile(filename) {
return function (cb) {
fs.readFile(filename, { encoding: "utf-8" }, cb);
};
}
run3(function* () {
console.log("before read");
const content = yield readfile("test.txt");
console.log("file data:", content);
console.log("after read");
});
// 输出结果
// ----- 异步任务执行器 -----
// before read
// file data: Hello,runner!
// after read
网友评论