如何在循环中对 es6 生成器执行异步任务

How to perform an async task against es6 generators in loop

本文关键字:执行 异步 任务 es6 循环      更新时间:2023-09-26

我了解如何使用生成器使异步代码看起来不错。我有一个简单的生成器*all,它需要一个page,将返回一个值。

然后我有另一个生成器*allDo,它将对第 1 到 30 页使用 *all,对于每个结果,执行一些异步task

然后我有另一个生成器*allBatchDo,它将批处理 3 页,并执行一些异步task

function mockPromise(value) {
  return Promise(function(resolve, reject) {
    resolve(value);
  });
}
function *all(page) {
  var ls = yield mockPromise("page " + page);
  // do all kinds of promises
  return yield ls;
};
function *allDo(task) {
  var page = 1;
  while (true) {
    var res = yield * all(page);
    res = yield task(res);
    if (page == 30) {
      break;
    }
    page++;
  }
}
function *allBatchDo(task) {
  var page = 1;
  var arr = [];
  while (true) {
    var res = yield * all(author, page);
    arr.push(res);
    if (arr.length >= 3) {
      yield task(arr);
      arr = [];
    }
    if (page == 30) {
      break;
    }
    page++;
  }
}
function logTask(res) {
  return mockPromise(res).then(function(v) {
    console.log(v);
  });
}

这些生成器的示例用法如下:

// return a single page promise
async(all(1)).then(function(value) { console.log(value); });
// do `logTask` for all pages 1 thru 30
async(allDo(logTask));
// do `logTask` for all pages with batches of 10
async(allBatchDo(logTask));

问题是,这是对 es6 异步功能的合法使用,还是我的用例有一个抽象的内置解决方案?

如果你想使用生成器进行异步,那么你的代码是有效的。ES6 只包含异步操作的承诺。ES7 将具有异步/等待。 你也可以使用一个好的库:https://github.com/kriskowal/q 或只使用原生承诺 Promise.所有这些都没有生成器。

我会说这段代码可能很慢,因为你使用的是yield*,所有任务都将按顺序运行,可能会花费比必要的更多的时间(假设mockPromise做了一些io)你可能更好地产生Promise.all或只使用承诺

此外,您对while(true)的用法非常奇怪。

以下是一些可以帮助您的异步运行器

的链接

http://davidwalsh.name/concurrent-generators 和http://spion.github.io/posts/analysis-generators-and-other-async-patterns-node.html