Express中返回错误的Bluebird基于promise的请求处理程序

时间:2014-11-01 08:54:49

标签: node.js express redis promise bluebird

我正在使用Express(4.x),Redis(2.8)和Bluebird(2.x) - 需要将多个Redis调用串起来以返回响应:

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                   扔掉;                            ^错误:发送后无法设置标题。

有什么想法吗?我是蓝鸟的新手,可能搞砸了......

2 个答案:

答案 0 :(得分:0)

您应该将eventdates替换为.done

答案 1 :(得分:-1)

为了澄清,正如Benjamin在下面指出的那样,您的问题是您在响应对象已经发送到客户端之后尝试设置标头。我不确定是否有其他中间件正在返回响应,或者它是否与.done / .catch有关。我会尝试下面的代码来结束你的承诺链,虽然我不确定它会有所帮助。另一个提示 - 每个蓝鸟文档,你不需要使用'完成',尽管你可以(bluebird .done docs)。如果你确实使用了.done,它应该是你的承诺链中的最后一件事(尽管你可以同时拥有已经完成和拒绝的处理程序,就像.then一样)。

.done(function(inOffers){
    console.log('InOffers: ',inOffers);
    res.json({inOffers: inOffers})
}, function(err){
    console.log((new Date).toUTCString()+" [ERROR] ", err);
    res.writeHead(500);
    res.end();
});