javascript - Bluebird map 提前返回

标签 javascript mongodb bluebird

我正在使用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);

有人知道我可能做错了什么吗?

最佳答案

我发现这里存在三个主要错误:

  1. Bluebirds .map() 需要一个返回 Promise 的回调。
  2. 正在执行 console.log(items).then() 句柄必须返回 items,以便结果 promise 仍然具有 items 作为解析值。
  3. 当您调用 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/

相关文章:

php - 尝试为 Symfony 安装 MongoDBBundle。使用 Composer 但无法解决

javascript - 返回 Promise,但得到 'Cannot read property ' then'of undefined'

node.js - bluebird promisifyAll() 和 then() 不与 Node require 一起使用

javascript - 存储十六进制 HTML 颜色作为数值转换返回不同的颜色

javascript - 文本区域无法正确呈现

javascript - 根据相机 View 变化计算对象旋转

javascript - Restify & Bluebird - 如何将错误从 catch block 传递到 restify 错误处理程序?

javascript - 如何在 WooCommerce 表单中禁用自动对焦?

javascript - 使用适用于 Node JS 的 mongodb native 驱动程序记录所有查询

Mongodb选择片键