我正在使用Express(4.x),Redis(2.8)和Bluebird(2.x) - 需要將多個Redis調用串起來以返回響應:Bluebird基於承諾的Express請求處理程序返回錯誤
var promise = require('bluebird');
var redis = require('redis');
var redis = redis.createClient(6379,process.env["REDIS_ENDPOINT"],{});
promise.promisifyAll(redis);
// GET
exports.inOffers = function (req, res) {
return redis.smembersAsync('advertisers')
.map(function(advId){
console.log('advId',advId);
return redis.smembersAsync('advertiser:'+advId+':inoffers')
.map(function(inOfferId){
console.log('offerId: ',inOfferId);
return redis.hgetallAsync('advertiser:'+advId+':inoffer:'+inOfferId);
})
})
.done(function(inOffers){
console.log('InOffers: ',inOffers);
res.json({inOffers: inOffers})
})
.catch(function(err){
console.log((new Date).toUTCString()+" [ERROR] ", err);
res.writeHead(500);
res.end();
});
};
根據日誌,數據正確地從Redis的聚集,但我得到了下面的錯誤,而不是響應:
/var/app/current/node_modules/bluebird/js/main/async.js:95 throw res.e; ^Error: Can't set headers after they are sent.
任何想法?我是新來的藍鳥,可能是搞砸了一些東西...
絕對不是問題,更換
.done
。 OP的問題並不在於承諾 - 這就是它的說法 - 他將應用程序中的標題發送到應用程序的其他地方,現在嘗試再次發送它們(例如,將內容類型設置爲JSON)。如果您刪除該代碼的res/req部分,它就可以工作。 '.done'是古老的承諾庫沒有檢測到未處理的拒絕的遺留物。 – 2014-11-01 23:17:34我意識到問題在於響應試圖發送兩次,我認爲它可能與完成後的catch有關,所以如果res.json中有錯誤,catch可能會被觸發。我改變了它,所以只有一個響應方法可以被調用。我也在花時間指出他不必使用.done,而且.done後面的.cone並沒有真正的意義。這沒有意義,是嗎? – 2014-11-01 23:26:36
不,但是這可能是他真正的代碼,因爲'.done'返回'undefined'。 – 2014-11-01 23:34:23