我正在使用Bluebird.map
,但由于某种原因它提前返回了我的对象数组:
function returnInvoicePrice(items) {
return Bluebird.map(items, function(item) {
db.collection('products').find({
product_code : item.product_code
}).toArray(function(err, product) {
var invoice_price = product[0].invoice_price;
console.log('--product--');
console.log(product);
return product;
});
}).then(function(items) {
console.log('--items w/ invoice price--'); // this prints BEFORE my console.log(product) for some reason...
console.log(items);
}).catch(function(error) {
console.log('--bluebird error in returning price for each item--');
console.log(error);
});
}
returnInvoicePrice(items);
有人知道我可能做错了什么吗?
最佳答案
我发现这里存在三个主要错误:
- Bluebirds
.map()
需要一个返回 Promise 的回调。 - 正在执行
console.log(items)
的.then()
句柄必须返回 items
,以便结果 promise 仍然具有items
作为解析值。 - 当您调用
returnInvoicePrice()
时,您必须使用.then()
来检索其值。该函数返回一个 Promise,它是一个主 Promise,它监视.map()
中的所有其他 Promise。
传递给 Bluebird.map()
的函数需要返回一个 promise ,该 promise 在异步操作完成时得到解决。如果它不返回任何内容或返回一个普通值,则 Bluebird 无法等到异步操作完成,因此将比您想要的更快返回。
如果您的版本尚不支持 Promise,可以使用 mongodb-promise 等软件包。这将为您提供 mongodb 的 promise 接口(interface),或者您可以使用 Bluebird 的 .promisify()
或 .promisifyAll()
来 promise mongodb 中的接口(interface)。
最新版本的 mongodb for Node 在其所有异步接口(interface)中都支持 Promise,因此您可以直接返回它提供的 Promise。
出现于this doc for the latest mongodb xxx.find().toArray()
返回一个 Promise,因此您可以像这样直接从 .map()
回调返回该 Promise(并且还可以修复其他问题)错误):
function returnInvoicePrice(items) {
return Bluebird.map(items, function(item) {
// return promise here
return db.collection('products').find({
product_code : item.product_code
}).toArray(function(err, product) {
var invoice_price = product[0].invoice_price;
console.log('--product--');
console.log(product);
return product;
});
}).then(function(items) {
console.log('--items w/ invoice price--'); // this prints BEFORE my console.log(product) for some reason...
console.log(items);
// also have to return items here
return items;
}).catch(function(error) {
console.log('--bluebird error in returning price for each item--');
console.log(error);
});
}
// have to use `.then()` on the returned promise here
returnInvoicePrice(items).then(function(items) {
// can access items here
});
关于javascript - Bluebird map 提前返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41773285/