【问题标题】:Bluebird promisify Mongoose蓝鸟许诺猫鼬
【发布时间】:2015-11-09 11:16:18
【问题描述】:

我只使用了几天的 Bluebird,仍然感到困惑。这是我正在处理的代码:

router.route('/:name')
        .get(function (req, res) {
                var values = [];
                 Tag.findOneAsync({'name': req.params.name}, {urlId: 1, _id: 0}).then(function (data) {
                    data['urlId'].forEach(function (urlId) {
                        Urls.findByIdAsync(urlId).then(function (result) {
                            values.push(result);
                        }).catch(function (err) {
                            res.status(500).send(err);
                        });
                    });
                }).catch(function (err) {
                    res.status(500).send(err);
                });

                res.send(values);
     });

在此代码中,响应为空 values 。所以我尝试以这种方式组织代码:

router.route('/:name')
        .get(function (req, res) {
            var  prom = new Promise(function(resolve, reject) {
                var values = [];
                Tag.findOneAsync({'name': req.params.name}, {urlId: 1, _id: 0}).then(function (data) {
                    data['urlId'].forEach(function (urlId) {
                        Urls.findByIdAsync(urlId).then(function (result) {
                            values.push(result);

                        }).catch(function (err) {
                            reject(err);
                        });
                    });
                }).catch(function (err) {
                    reject(err);
                });
                resolve(values);
            });
            prom.then(function (values) {
                res.send(values);
            });

结果还是一样。那么我如何组织代码,以便在完成data['urlId'].forEach 操作后得到响应。

【问题讨论】:

  • 您可以尝试在第二个示例中的第一个函数末尾添加一个返回,以便在解决它后返回承诺吗?你可能不会退回它。
  • 如果你对模块进行承诺,异步方法已经返回承诺对象,所以你不需要手动创建承诺。此外,在 then 语句中使用 promise 时,您需要返回它

标签: node.js express mongoose


【解决方案1】:

见我的 cmets。您应该执行以下操作。因为你已经承诺了 mongoose,所以异步方法已经返回了 Promise,所以你不需要创建一个新的 Promise 来解决或拒绝它们。您还需要在 then 语句中返回任何返回承诺的代码。

router.route('/:name')
.get(function (req, res, next) {
    var values = [];
    Tag.findOneAsync({'name': req.params.name}, {urlId: 1, _id: 0}).then(function (data) {
        return promise.each(data['urlId'], function (urlId) {
            return Urls.findByIdAsync(urlId).then(function (result) {
                values.push(result);
            });
        });
    })
    .then(function () {
        res.send(values);
        //return next();    
    })
    .caught(function (err) {
        res.status(500).send(err);
        //return next();
    });
});

或者更干净地使用promise.map

var mongoose = require( 'mongoose' );
var Promise = require('bluebird');
Promise.promisifyAll( mongoose );

router.route('/:name')
.get(function (req, res, next) {
    Tag.findOneAsync({'name': req.params.name}, {urlId: 1, _id: 0}).then(function (data) {
        return Promise.map(data['urlId'], function (urlId) {
            return Urls.findByIdAsync(urlId).then(function (result) {
                return result;
            });
        });
    })
    .then(function (values) {
        res.send(values);
        //return next();    
    })
    .caught(function (err) {
        res.status(500).send(err);
        //return next();
    });
});

【讨论】:

  • 现在抛出 500 错误“错误:发送后无法设置标头。”
  • 在 get 中的 catch 语句之后的某处是否还有另一个 send 语句?也许尝试res.send(500, err) 而不是res.status(500).send(err) 所有发送都需要包含在promise 方法中,因为异步方法将在它们解决之前执行并移动到下一个代码块。
  • 不,我没有其他发送声明
  • 您能否删除被捕获的语句并查看是否抛出错误并从那里进行故障排除。您遇到的错误通常是在尝试发送结果之后发生。
  • 去掉catch语句后出现新错误Unhandled rejection ReferenceError: promise is not defined
猜你喜欢
  • 2015-10-27
  • 2015-11-19
  • 2016-06-04
  • 2016-11-21
  • 2016-09-23
  • 2016-06-10
  • 2015-03-05
  • 2015-03-06
  • 2016-05-25
相关资源
最近更新 更多