2015-11-09 52 views
0

我只使用了蓝鸟几天,还是我confused.Here是我工作的代码:此代码蓝鸟promisify猫鼬

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操作后得到响应。

+0

可以尝试将在第二个示例的第一个函数的最后回报,这样的承诺是解决它后返回?你可能不会返回它。 – blamb

+0

如果您承诺使用模块,则异步方法已经返回承诺对象,因此您不需要手动创建承诺。另外,当在一个语句中使用promise时,你需要返回它 – vbranden

回答

2

查看我的评论。你应该做更像下面的事情。既然你已经promonified猫鼬的异步方法已经返回承诺,所以你不需要创建一个新的承诺来解决或拒绝他们。你也需要返回任何在then语句中返回promise的代码。

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(); 
    }); 
}); 
+0

现在抛出500错误“错误:发送后无法设置标题。” – pyprism

+0

你在获得被发现的声明后是否还有其他发送声明?可能尝试'res.send(500,err)'而不是'res.status(500).send(err)'所有的发送都需要包含在promise方法中,因为异步方法会执行并移动到下一个代码块解决之前。 – vbranden

+0

不,我没有其他发送语句 – pyprism