forEach在Node.js中使用生成器

时间:2014-07-16 08:24:09

标签: node.js foreach mongoose generator koa

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

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

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

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

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

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

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

我也没有得到res变量的结果。我尝试使用“generator-foreach”模块,但这并不是这样的。

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

3 个答案:

答案 0 :(得分:21)

你可以yield数组,所以只需在另一个地图中映射你的异步承诺

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

答案 1 :(得分:8)

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

这是一个老问题,但由于它还没有正确的答案,它出现在谷歌搜索关键术语“迭代器和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 }

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

答案 2 :(得分:6)

谢谢大家,我使用'CO'模块完成了这项工作。感谢。

var co = require('co');

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

编辑:使用最新版本的CO,你需要co.wrap()来实现这个目的。