【问题标题】:Looping with promises in node returns same response在节点中使用 Promise 循环返回相同的响应
【发布时间】:2014-08-02 01:27:37
【问题描述】:

当使用 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)
});

输出: 结果页码:['1'], 结果页码:['1'], 结果页码:['1'], 结果页码:['1'],

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

【问题讨论】:

  • var deferred = Q.defer();移动到你的循环中。
  • 如果您有多个promises,则需要多个defer 对象。您正在为所有承诺重用相同的defer,这很可能是问题的原因。

标签: javascript node.js promise q


【解决方案1】:

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

我的建议是始终承诺尽可能低的原语

在我们的例子中。我会承诺Clients .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。在我看来,这要好得多,而且更不容易出错。

【讨论】:

    【解决方案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);
    });
    

    【讨论】:

    • 啊。工作完美!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-11-28
    • 2021-05-11
    • 2017-01-09
    • 1970-01-01
    • 2018-06-07
    • 2021-04-26
    • 2020-02-11
    • 1970-01-01
    相关资源
    最近更新 更多