我正在使用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的语言素养缺乏了解。但你们能帮助我找到一种方法吗?
答案 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()来实现这个目的。