【问题标题】:Advance deferred looping in while function在while函数中推进延迟循环
【发布时间】:2015-02-11 20:49:34
【问题描述】:

在 SO Deferred in $.when while looping an array 中扩展这个问题

我有这个控制结构:-

function oldSync(array) { 
  var output = []; // to store the output
  $.each( array, function(key,value) { // runs sequentially
    var item1 = SyncFunction_A(input);
    var item2 = SyncFunction_B(input); 
    output.push({'a': item1, 'b': item2});
  });
  return doSomething(output); // process all output
}

接下来,我将 SyncFunction() 替换为 AsyncFunction(),

问题:如何将其转换为延迟或异步函数?

function newAync(array) { //
  var output = [];
  $.each( array, function(key,value) { // runs sequentially
    var item1 = AsyncFunction_A(input);
    var item2 = AsncFunction_B(input); 
    item1.then(item2).then(function(data) {
        output.push({'a': data[0], 'b': data[1] });
    }
  });
  return doSomething(output); // FAIL, it doesn't wait for Async
}

【问题讨论】:

    标签: jquery asynchronous


    【解决方案1】:

    实际上,我更喜欢在沙箱中检查代码。但我希望你能抓住主要思想

    function newAync(array) { //
      var output = [],
        promises = [];
      $.each( array, function(key,value) { // runs sequentially
        var item1 = AsyncFunction_A(input);
        var item2 = AsncFunction_B(input); 
        var promise = item1.then(item2).then(function(data) {
            output.push({'a': data[0], 'b': data[1] });
        };
    
        promises.push(promise);
      });
    
      var defer = $.Deferred();
    
      $.when.apply($, promises).done(function() {
        defer.resolve(doSomething(output));
      });
    
      return defer.promise();
    }
    

    【讨论】:

    • 主要思想是正确的。注意:返回 defer.promise() 意味着承诺会沿着食物链上升。例如:main() -> subroutine() -> newAsync(),因此 main() 需要 .then().done()
    • 是的,我返回承诺,获得订阅结果的能力
    • 它链接到 main() 例程,因为 newAsync() 可能有 4 层或更多层深,因此变得复杂。更容易重写 main() 中的逻辑以直接调用 newAsync() 并避免将承诺传递到食物链。
    【解决方案2】:

    您需要做的是利用回调函数来使用同步函数。我不知道你的 A 和 B 函数是什么,它们应该做什么,或者这些值代表你存储在 output 数组中的什么。

    这是一个示例,您将一组 url 传递给一个函数,当您获得每个 url 的结果时,它会执行一个回调:

    function func(urls_array, callback){ // The "callback" will be called when all results have returned.
      var results = []; // Array to store the results of each $.get
      for(var i=0;i<urls_array.length;i++){ // Loop through each url
        $.get(urls_array[i], function(x){ // get the data at the url
          results.push(x); // store the results of this get function
          if(results.length == urls_array.length){ // If all urls have returned
            callback(results); // execute the callback function letting it know that you have finished
          }
        });
      }
    }
    

    也许这将帮助您了解同步函数(带有回调的函数)的工作原理。

    如果您想对您的问题更具体一点,我们无法提供可能有帮助的答案,但您所问的内容过于笼统,并且可能未为我们定义诸如 SyncFunction_A 之类的内容。

    【讨论】:

    • 对于回调,我会采用像 async.js 这样的库来简化上面的编码(即:避免回调地狱)。答案是正确的。
    猜你喜欢
    • 1970-01-01
    • 2020-02-22
    • 2013-01-24
    • 2018-04-05
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    相关资源
    最近更新 更多