日常刻书

异步任务执行

2021-01-30  本文已影响0人  F_wind

《深入理解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
上一篇下一篇

猜你喜欢

热点阅读