forEach在Node.js中使用生成器

Maz*_*med 15 foreach generator mongoose node.js koa

我正在使用Koa.js框架和Mongoose.js模块.

通常从MongoDB获取结果我的代码如下:

var res = yield db.collection.findOne({id: 'my-id-here'}).exec();
Run Code Online (Sandbox Code Playgroud)

但我需要为名为'items'的数组的每个元素执行此行.

items.forEach(function(item) {
  var res = yield db.collection.findOne({id: item.id}).exec();
  console.log(res)  // undefined
});
Run Code Online (Sandbox Code Playgroud)

但是这个代码没有运行,因为函数中的yield.如果我写这个:

items.forEach(function *(item) {
  var res = yield db.collection.findOne({id: item.id}).exec();
  console.log(res)  // undefined
});
Run Code Online (Sandbox Code Playgroud)

我也没有得到res变量的结果.我试图使用' generator-foreach '模块,但这并没有像这样工作.

我知道这是我对Node.js的语言素养缺乏了解.但是你能帮助我找到一种方法吗?

Umi*_*mov 21

您可以使用yield数组,因此只需在另一个地图中映射您的异步保证

var fetchedItems = yield items.map((item) => {
   return db.collection.findOne({id: item.id});
});
Run Code Online (Sandbox Code Playgroud)


Jor*_*Riv 9

接受的答案是错误的,没有必要使用库,数组已经是可迭代的.

这是一个老问题,但由于它还没有正确的答案,它出现在谷歌搜索关键术语"迭代器和forEach"的第一页上,我将回答这个问题:

没有必要迭代数组,因为数组已经符合可迭代API.

在你的生成器内部只使用"yield*array"(注意*)yield*表达式用于委托给另一个生成器或可迭代对象

例:

let arr = [2, 3, 4];

    function* g2() { 
      yield 1;
      yield* arr;
      yield 5;
    }

    var iterator = g2();

    console.log(iterator.next()); // { value: 1, done: false }
    console.log(iterator.next()); // { value: 2, done: false }
    console.log(iterator.next()); // { value: 3, done: false }
    console.log(iterator.next()); // { value: 4, done: false }
    console.log(iterator.next()); // { value: 5, done: false }
    console.log(iterator.next()); // { value: undefined, done: true }
Run Code Online (Sandbox Code Playgroud)

有关示例和深入信息,请访问:https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*


Maz*_*med 6

谢谢大家,我使用' CO '模块做到了这一点.谢谢.

var co = require('co');

items.forEach(co(function* (item) {
  var img = yield db.collection.findOne({id: item.id}).exec();
}));
Run Code Online (Sandbox Code Playgroud)

编辑:使用最新版本的CO,你需要co.wrap()才能工作.

  • 如果你使用循环`for(x = 0; x <items.length; x ++)`的标准,那么它将起作用,因为没有回调,因此允许你使用yield而不将它包装在另一个`co`中. (5认同)