javascript - 用于顺序执行同步和异步函数的 jQuery Deferred 和 Promise

标签 javascript jquery asynchronous promise synchronous

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

当调用 deferred.resolve() 时,函数 a、b 和 c 应该按该顺序执行 我希望函数 b 被执行,但所有函数都会立即执行决议被称为。

代码如下:

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 的延迟解决之前被调用,c 在 b 的延迟解决之前被调用。

最佳答案

对于 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

关于javascript - 用于顺序执行同步和异步函数的 jQuery Deferred 和 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20122227/

相关文章:

javascript - 滚动覆盖的内容

javascript - Python 编码 - 没有任何作用

javascript - 在 Javascript `Component` IF/ELSE 语句内隐藏 `<Canvas>` 图像

javascript - 无法让 vimeo 视频与 fancybox 一起使用 - 我觉得我已经尝试了一切

c# - 测试异步方法时如何使用序列?

javascript - 什么时候使用 process.nextTick 最好?

javascript - PHP网页上的进度条

javascript - 无限滚动仅在首页起作用

Javascript Promise.all()

javascript - 单击鼠标调整图像大小