循环使用节点中的promises会返回相同的响应

时间:2014-06-11 20:43:50

标签: javascript node.js promise q

当使用q时,我得到相同的响应它循环的次数:

function start() {
    var the_promises = [];
    var api_info = config.AFV
    var deferred = Q.defer();
    var extPath = '/search/'
    var callType = 'GET'
    var mymd = buildmd5(api_info, extPath, callType);

    for(var page=1;page<4;page++) {

        console.log('getting page:'+page)
        new Client().get(url'+page, function(data, response){
            deferred.resolve(data);
        });
        the_promises.push(deferred.promise);
    }  
    return Q.all(the_promises);
}

start().then(function (clips) {
    inspect(clips)
});

输出:     resultPageNumber:[&#39; 1&#39; ]     resultPageNumber:[&#39; 1&#39; ]     resultPageNumber:[&#39; 1&#39; ]     resultPageNumber:[&#39; 1&#39; ],

我觉得我可能有var deferred = Q.defer();在错误的地方,它嗤之以鼻地保存到不同的承诺。我知道这个版本的代码不起作用,但我只关心这些承诺。谢谢!

2 个答案:

答案 0 :(得分:2)

您需要为每个新客户创建一个新的延期。并在紧接调用的函数中抛出该循环体以正确定义var。

function start() {
    var the_promises = [];
    var api_info = config.AFV;
    var extPath = '/search/';
    var callType = 'GET';
    var mymd = buildmd5(api_info, extPath, callType);

    for(var page=1;page<4;page++) {
        (function() {
            var deferred = Q.defer();
            console.log('getting page:'+page);
            new Client().get('url'+page, function(data, response){
                deferred.resolve(data);
            });
           the_promises.push(deferred.promise);
        }());
    }  
    return Q.all(the_promises);
}

start().then(function (clips) {
    inspect(clips);
});

答案 1 :(得分:0)

我不喜欢现有的解决方案,风险很大。如果一个承诺错误会怎样?如果您的代码中还有其他问题,会发生什么?

我建议始终宣传可能的最低原语

在我们的案例中。我会宣传Client .get方法。

Client.prototype.getAsync = function(url){
   var d = Q.defer(); // or better, using Q.Promise(
   // please also consider adding a d.reject on the error case.
   this.get(url, function(data){ d.resolve(data); }); 
   return d.promise;
}

这个新的api可以让你这样做:

var promises = [1,2,3,4].map(function(page){
    return new Client().getAsync("url"+page);
});
return Q.all(promises);

然后获得与Dan的回答类似的API。在我看来,这样做更好,而且容易出错。