Javascript 如何暂停在链中间延迟的jQuery的分辨率?

Javascript 如何暂停在链中间延迟的jQuery的分辨率?,javascript,jquery,jquery-deferred,promise,Javascript,Jquery,Jquery Deferred,Promise,我试图将序列化逻辑强制应用到网页上的一组异步活动上。我很确定我想使用jQuery deferred对象,但我遇到了一个问题,即我想执行的函数取决于用户何时决定通过单击各种按钮进行选择。我正在使用以下JSFIDLE想法寻求帮助: 考虑由4个按钮组成的序列。单击时,每个按钮将禁用自身并启用下一个按钮。每个按钮在启用后才应设置其事件。只有在启用第三个按钮后,才能执行添加的任务(在本例中为警报) 基本HTML代码 不正确的控制逻辑 可以在这里看到JSFIDLE: 我最初的理解是,我可以使用.then()

我试图将序列化逻辑强制应用到网页上的一组异步活动上。我很确定我想使用jQuery deferred对象,但我遇到了一个问题,即我想执行的函数取决于用户何时决定通过单击各种按钮进行选择。我正在使用以下JSFIDLE想法寻求帮助:

考虑由4个按钮组成的序列。单击时,每个按钮将禁用自身并启用下一个按钮。每个按钮在启用后才应设置其事件。只有在启用第三个按钮后,才能执行添加的任务(在本例中为警报)

基本HTML代码 不正确的控制逻辑 可以在这里看到JSFIDLE:


我最初的理解是,我可以使用.then()函数将函数链接到延迟函数中。显然,这不起作用,因为第3步中的附加任务会在页面加载时触发。我需要如何调整此场景的控制或逻辑来解决每个步骤,直到相应的按钮按下被注册为止?

我不明白您为什么需要延迟,但我知道您没有使用它们

试试这样的

firstResolution  = $.Deferred();
secondResolution = $.Deferred();

function stepOne() {
   //disable button one
   //enable button two
   return firstResolution;
}

function stepTwo() {
    //disable button two
    //enable button three
}

$.when(stepOne()).then(stepTwo);

$.when(secondResolution).then(stepThree);

// This is also acceptable (and maybe better?)
// $.when(firstResolution, seconResolution).then(stepThree);

// when you resolve, then step two will fire.
firstResolution.resolve();

// and for stepThree to fire
secondResolution.resolve();

我不明白你为什么需要延期,但我知道你没有使用它们

试试这样的

firstResolution  = $.Deferred();
secondResolution = $.Deferred();

function stepOne() {
   //disable button one
   //enable button two
   return firstResolution;
}

function stepTwo() {
    //disable button two
    //enable button three
}

$.when(stepOne()).then(stepTwo);

$.when(secondResolution).then(stepThree);

// This is also acceptable (and maybe better?)
// $.when(firstResolution, seconResolution).then(stepThree);

// when you resolve, then step two will fire.
firstResolution.resolve();

// and for stepThree to fire
secondResolution.resolve();

您的代码示例并不像您认为的那样。您所做的只是在解决
oDeferredObj
后直接添加到要完成的事情列表中。此外,还有一个问题是如何解决任务何时实际“完成”的问题,而您的代码并没有给出相应的标签

这似乎是我不久前在另一个问题中解决过的问题,但我不确定我是否希望得到我当时给出的答案,所以让我重新尝试

你所寻求的是一种将新的承诺联系在一起的方式。我想,你还想知道承诺何时得到解决(或拒绝)

异步地将数据从一个承诺传递到另一个承诺的一个好方法是使用
管道将它们链接起来,但是由于您希望从UI事件中触发任务的完成,我很难想象比下面更好的东西

我不会发誓这是最好的方法,我能想到的处理这个问题的最简单方法是创建一个实用函数,它接受给定的承诺和“任务”,创建一个新的承诺,让您的任务决定如何处理该承诺,但只有在给定的承诺得到解决后,才返回新的承诺

var nextStage = function (promise, task) {
  var oDeferredObj = $.Deferred();
  promise.then(function () {
    task(oDeferredObj);
  });
  return oDeferredObj;
}
然后,可以使用此功能将任务菊花链连接在一起:

/* Creation of deferred and initial wiring */
var p1;
var starterObj = $.Deferred();
p1 = starterObj;
p1 = nextStage(p1, fnDoStageOne);
p1 = nextStage(p1, fnDoStageTwo);
p1 = nextStage(p1, fnDoStageThree);
p1 = nextStage(p1, fnDoStageFour);
p1.done(function () {
  alert("All stages done.");
})
$("#start").one("click", function (event, ui) {
  //fire it up.
  $("#start").prop("disabled", true);
});
很明显,您需要做一些事情来表明某个特定任务已在某个时间完成,例如:

var fnDoStageOne = function (promise) {
  //setup, etc.
  $("#btn1").one("click", function (event, ui) {
    //.. whatever needs to happen  in the ui.
    //STAGE ONE IS ONLY DONE AFTER THIS POINT
    promise.resolve();
  });
};
请注意,我只是给了你一个承诺成功的开始。当他们失败时,多做一点是明智的。此外,如果希望将数据从一个承诺传递到另一个承诺,则可能需要
管道
,等等


JSFIDLE中的完整源代码(从您的源代码修改而来)

您的代码示例并不像您认为的那样。您所做的只是在解决
oDeferredObj
后直接添加到要完成的事情列表中。此外,还有一个问题是如何解决任务何时实际“完成”的问题,而您的代码并没有给出相应的标签

这似乎是我不久前在另一个问题中解决过的问题,但我不确定我是否希望得到我当时给出的答案,所以让我重新尝试

你所寻求的是一种将新的承诺联系在一起的方式。我想,你还想知道承诺何时得到解决(或拒绝)

异步地将数据从一个承诺传递到另一个承诺的一个好方法是使用
管道将它们链接起来,但是由于您希望从UI事件中触发任务的完成,我很难想象比下面更好的东西

我不会发誓这是最好的方法,我能想到的处理这个问题的最简单方法是创建一个实用函数,它接受给定的承诺和“任务”,创建一个新的承诺,让您的任务决定如何处理该承诺,但只有在给定的承诺得到解决后,才返回新的承诺

var nextStage = function (promise, task) {
  var oDeferredObj = $.Deferred();
  promise.then(function () {
    task(oDeferredObj);
  });
  return oDeferredObj;
}
然后,可以使用此功能将任务菊花链连接在一起:

/* Creation of deferred and initial wiring */
var p1;
var starterObj = $.Deferred();
p1 = starterObj;
p1 = nextStage(p1, fnDoStageOne);
p1 = nextStage(p1, fnDoStageTwo);
p1 = nextStage(p1, fnDoStageThree);
p1 = nextStage(p1, fnDoStageFour);
p1.done(function () {
  alert("All stages done.");
})
$("#start").one("click", function (event, ui) {
  //fire it up.
  $("#start").prop("disabled", true);
});
很明显,您需要做一些事情来表明某个特定任务已在某个时间完成,例如:

var fnDoStageOne = function (promise) {
  //setup, etc.
  $("#btn1").one("click", function (event, ui) {
    //.. whatever needs to happen  in the ui.
    //STAGE ONE IS ONLY DONE AFTER THIS POINT
    promise.resolve();
  });
};
请注意,我只是给了你一个承诺成功的开始。当他们失败时,多做一点是明智的。此外,如果希望将数据从一个承诺传递到另一个承诺,则可能需要
管道
,等等


JSFIDLE中的完整源代码(从您的源代码修改而来)

也许您想要使用队列,它是为可能耗时的事件序列而设计的。它们是为<代码>$提供动力的同一个系统;一次只执行一个函数,而下一个函数直到第一个函数明确表示它已使用
$完成时才执行。dequeue

另一方面,延迟实际上是指一旦数据可用就消费数据


见和。还可以看到我写的这个,它有示例代码和一个JSFIDLE。

也许您想使用队列,它是为可能耗时的事件序列而设计的。它们是为<代码>$提供动力的同一个系统;一次只执行一个函数,而下一个函数直到第一个函数明确表示它已使用
$完成时才执行。dequeue

另一方面,延迟实际上是指一旦数据可用就消费数据


见和。还可以看到我写的这篇文章,它有示例代码和一个JSFIDLE。

如果一个按钮被禁用,click事件将永远不会触发,那么为什么不将所有事件侦听器绑定一次呢?因为这特别代表了如何处理延迟对象的问题。我试图拼凑出如何将它们用于更复杂的问题,所以我试图将它们与