如何在node.js中使用q.defer来链接promise?

exports.list = function(req, res) { var location_parent_id = req.params.location_parent_id; var query = { company_id: req.company_id }; if(location_parent_id) { query.location_parent_id = location_parent_id; Location.findOne({someQuery}, function(err, location) { response.location = location; }); } else { query.location_parent_id = { '$exists': false } } Location.find(query, function(err, locations) { if(err) { response = { status: 'error', error: err } } else if(!locations) { response = { status: 'error', error: 'Location not found' } } else { response = { status: 'ok', locations: locations } return res.json(response); } }); } 

这是我的代码。 如果有一个location_parent_id ,那么我也想返回这个位置。 而不是进入asynchronous和callback地狱,我认为承诺是一个很好的方式来执行我想要的。 只是不确定如何。

根本不需要使用q.defer 。 您可以使用Node-callback接口方法立即获得承诺。 要链接方法,请使用.then()

 exports.list = function(req, res) { var result = Q.ninvoke(Location, "find", { company_id: req.company_id, location_parent_id: req.params.location_parent_id || {'$exists': false} }).then(function(locations) { if (!locations) throw new Error('Location not found'); return { status: 'ok', locations: locations }; }); if (req.params.location_parent_id) { // insert the step to wait for the findOne (in parallel), and merge into res result = Q.all([result, Q.ninvoke(Location, "findOne", {someQuery})]) .spread(function(res, location) { res.location = location; return res; }); } result.catch(function(err) { return { status: 'error', error: err.message }; }).done(function(response) { res.json(response); }); }