19

我正在使用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 的语言素养缺乏了解。但是你们能帮我找到一种方法吗?

4

3 回答 3

28

您可以yield使用数组,因此只需将您的异步承诺映射到另一个地图中

var fetchedItems = yield items.map((item) => {
   return db.collection.findOne({id: item.id});
});
于 2015-08-14T03:24:10.903 回答
11

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

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

不需要迭代数组,因为数组已经符合可迭代 API。

在您的生成器中,只需使用“yield* 数组”(注意 *)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 *

于 2016-07-18T21:24:31.047 回答
7

谢谢大家,我已经使用“ CO ”模块完成了这项工作。谢谢。

var co = require('co');

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

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

于 2014-07-17T05:00:45.710 回答