【问题标题】:jQuery Deferred and Promise for sequential execution of synchronous and asynchronous functionsjQuery Deferred 和 Promise 用于同步和异步函数的顺序执行
【发布时间】:2013-11-21 13:25:00
【问题描述】:

如果我想让同步和异步函数按特定顺序执行,我可以使用 jQuery Promise,但它似乎不像我期望的那样工作。

在调用 deferred.resolve() 时,函数 a、b 和 c 应按此顺序执行我希望函数 b 会被执行,但无论是否调用 resolve,所有函数都会立即执行。

代码如下:

function a(){
  var deferred = $.Deferred();
  setTimeout(function(){
    console.log("status in a:",deferred.state());
    //this should trigger calling a or not?
    deferred.resolve("from a");
  },200);
  console.log("a");
  return deferred.promise();
};
function b(){
  var deferred = $.Deferred();
  setTimeout(function(){
    console.log("status in b:",deferred.state());
    deferred.resolve("from b");
  },200);
  console.log("b");
  return deferred.promise();
}
//synchronous function
function c(){
  var deferred = $.Deferred();
  console.log("c");
  console.log("status in c:",deferred.state());
  deferred.resolve("from c");
  return deferred.promise();
}
function test(){
  fn=[a,b,c],i=-1,
  len = fn.length,d,
  d = jQuery.Deferred(),
  p=d.promise();
  while(++i<len){
    p=p.then(fn[i]);
  }
  p.then(function(){
    console.log("done");
  },
  function(){
    console.log("Failed");
  });
  d.resolve();
  //instead of the loop doing the following has the same output
  //p.then(a).then(b).then(c);
  //d.resolve();
}
test();

输出是:

a
b
status in c: pending
c
done
status in a: pending
status in b: pending

预期输出:

a
status in a: pending
b
status in b: pending
c
status in c: pending
done

尝试了以下修改的一些组合:

  d = jQuery.Deferred();
  setTimeout(function(){d.resolve();},100);
  var p=d.promise();
  while(++i<len){
    p.then(fn[i]);
  }

但是所有的结果都是一样的,b 在 a 的 deferred 被解决之前被调用,c 在 b 的 deferred 被解决之前被调用。

【问题讨论】:

    标签: javascript jquery asynchronous promise synchronous


    【解决方案1】:

    对于 1.8 之前的 jQuery,这是一个问题,但对于 jQuery 的新版本,这不再是一个问题:

    function test(){
      var d = jQuery.Deferred(), 
      p=d.promise();
      //You can chain jQuery promises using .then
      p.then(a).then(b).then(c);
      d.resolve();
    }
    test();
    

    DEMO

    下面是jQuery 1.7.2的demo

    DEMO

    【讨论】:

    • 附带说明,要让它在 jquery 1.7.2 中工作(使用扩展 jq 本机代码)jsfiddle.net/L5nud/2
    • jQuery
    • 如何使用它,如果a函数返回一个使用b函数的值等等。
    • @Cristian Chaparro A. a 函数的返回值作为参数传递给 b 函数。
    【解决方案2】:

    jQuery .pipe 而不是 .then。 1.8 简单地将.then 更改为.pipe

    【讨论】:

      【解决方案3】:

      旁注:当你在没有数组的情况下使用它时,你不必从一个承诺开始。 $.when({}).then(a).then(b) 可以解决问题。您只需要确保不要将a 放入when

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-08
        • 1970-01-01
        相关资源
        最近更新 更多