Q.all和一系列承诺似乎不起作用

时间:2014-06-06 13:22:25

标签: node.js q node-mysql

我正在尝试用Q做一些工作。我遍历并调用一个函数,该函数将数据保存到数据库并返回一个promise。一旦完成,我需要做其他事情,但Q.all完成,虽然我可以看到每个决心被调用。我疯了,有什么想法吗?

设置:

// save the divisions and then do the division checks
// data.divisions is an array of objects
var promises = [];
data.divisions.forEach(function(dd){
    var d = new grpl.division.Division(dd),
        p = d.save();
    promises.push(p);
});

Q.all(promises)
.then(function(){
    // do some other stuff here
    // this never actually gets called

}).fail(function(err){
    cb(err);
}).done();

这里是d.save()

Division.prototype.save = function(){
    var self = this
        d = Q.defer();

    getPool().getConnection(function(err, db){
        if(err){ d.reject(err); return false; }

        var fields = {
            division_id: self.division_id,
            season_id: self.season_id,
            title: self.title,
            cap: self.cap,
            display_order: self.display_order
        };

        db.query("INSERT INTO division SET ? ON DUPLICATE KEY UPDATE ?", [fields, fields], function(err, result) {
            if(err){ d.reject(err); return false; }
            d.resolve(true);// this does get resolved for each division
        });
    });

    return d.promise;
}

我不知道出了什么问题,但它只是停了下来,似乎没有解决我的Q.all电话。

更新 似乎保存的初始调用将正常运行,但后续保存调用似乎正在解析与第一次调用相同的承诺。我将保存代码的主体包装成一个变量函数,我从save调用它的工作但是我不是百分之百确定原因(原型继承是我的后备,只要JS真的让我感到困惑)。有任何解释或更好的方法吗?

Division.prototype.save = function(){
    var func = function(self){
        var d = Q.defer();

        d.promise.division_id = self.division_id;

        getPool().getConnection(function(err, db){
            if(err){ d.reject(err); return false; }

            var fields = {
                division_id: self.division_id,
                season_id: self.season_id,
                title: self.title,
                cap: self.cap,
                display_order: self.display_order
            };

            db.query("INSERT INTO division SET ? ON DUPLICATE KEY UPDATE ?", [fields, fields], function(err, result) {
                if(err){ d.reject(err); return false; }
                d.resolve(result);
            });
        });

        return d.promise;
    }

    return func(this);
}

1 个答案:

答案 0 :(得分:2)

好的,您的调试评论解决了问题,并明确了我所缺少的内容。这是一个令人难以置信的小错字,也是我建议在你的代码上使用像JSHint这样的东西的原因之一。

Division.prototype.save = function(){
    var self = this
        d = Q.defer();
你能看到吗?直到你的评论清楚地表明出了什么问题,我才这样做。

Division.prototype.save = function(){
    var self = this
                   ^
        d = Q.defer();

您错过了,,因此d是一个全局变量,而不是save中的范围,因此每次调用.save()时,您都会重写全局变量,并且您对resolvereject的所有尝试都将解析相同的全局,而不是每个保存调用的延迟。