我想发送Ajax请求并在数据到达时执行一些无关的操作。完成动作后,我想等待Ajax完成并执行其他动作。
具体来说,让我们看一下剥离的示例:
$.ajax({url: "/reqA"}) .done(updateA) .done($.ajax("/reqB").done(updateB)) .done(updateFinal)
updateFinal
应同步的完成之后执行updateA
和异步/reqB
和同步跟随updateB
。
上面的代码是错误的,因为所有后续.done()
操作均基于/regA
和的竞争条件发生在updateB
和之间updateFinal
。
我可以使用.then
以下代码修复代码:
$.ajax({url: "/reqA"}) .done(updateA) .then($.ajax("/reqB").done(updateB)) .done(updateFinal)
但是接下来我想updateA
在发送请求后运行/reqB
(因为JS引擎是单线程的,并且updateA
执行阻止了异步进程/reqB
!)。
以下代码不起作用:
$.ajax({url: "/reqA"}) .then($.ajax("/reqB").done(updateB)) .done(updateA) .done(updateFinal)
因为updateA
执行会延迟updateB
执行!
我认为该问题可以通过$.when
功能解决,但updateA
不是承诺,并且在官方$ .when文档中我看不到执行顺序的保证。它可能看起来像:
$.ajax({url: "/reqA"}) .then( $.when( $.ajax("/reqB").done(updateB), fakeResolvedPromiseWrapperAroundSyncFunc(updateA) ) ).done(updateFinal)
fakeResolvedPromiseWrapperAroundSyncFunc
jQuery库中有任何标准解决方案吗?
在启动异步并随后加入异步调用的结果之后,还有其他路径来运行同步代码吗?
在.done()
和.then()
处理程序中,您需要传递函数REFERENCES,而不仅仅是调用parens中的函数,以便能够控制执行的时间。
在承诺链中,您可以将同步函数或异步函数作为.then()
处理程序传递。如果传递异步函数,则只需要返回一个Promise,然后该Promise将被插入到Promise链中。同步函数仅在其转弯时被调用,然后链中的下一步将紧随其后(因为它是同步的)。
例如,更改此:
$.ajax({url: "/reqA"}) .done(updateA) .done($.ajax("/reqB").done(updateB)) .done(updateFinal)
对此:
$.ajax({url: "/reqA"}) .then(updateA) .then(function() { return $.ajax("/reqB").then(updateB) }).then(updateFinal);
或者,可以这样写:
$.ajax({url: "/reqA"}) .then(updateA) .then(function() { return $.ajax("/reqB"); }).then(updateB) .then(updateFinal);
这将执行ajax函数,当Ajax调用完成时,它将执行updateA()
。同步updateA()
完成后,它将调用匿名函数,然后该匿名函数执行/ reqB ajax调用。该ajax调用完成后,将执行updateB()
。如果updateB()
做了,那么updateFinal()
就会被调用。
并且,更改此:
$.ajax({url: "/reqA"}) .then($.ajax("/reqB").done(updateB)) .done(updateA) .done(updateFinal)
对此:
$.ajax({url: "/reqA"}) .then(function() { return $.ajax("/reqB").then(updateB); }).then(updateA) .then(updateFinal)
当您像以前一样直接在内部执行函数时,称为IMMEDIATELY,执行该函数的返回结果就是作为.then()
处理程序传递的结果。当您传递函数引用时,.then()
基础结构可以稍后再调用该函数。
您$.when()
也可以使用。当您要并行执行多个项目并且想知道它们何时完成时,可以使用它。上面的代码建议进行序列化执行(一件又一件)。
至于混合同步和异步代码,则可以很好地工作。序列中的第一个操作必须创建一个Promise,您可以从中链接.then()
处理程序。之后,任何给定.then()
处理程序的回调都可以执行以下任一操作:
它可以是同步的并返回常规值。 该值成为承诺链的已解析值,然后.then()
调用后续处理程序,将该值传递给它们。
它可以是同步的,并且不返回值。 此时,promise链的值为,undefined
并且.then()
链中的下一个处理程序将被调用。
它可以是同步的,并引发异常。 异常将成为当前Promise的拒绝值,并且.then()
将调用所有附加的拒绝处理程序,而不是解析处理程序。
它可以是异步的,也可以返回承诺。 这个新的promise插入到链中,并且.then()
在实现这个新的promise之前,不会调用后续的处理程序。是否调用后续的确定或拒绝处理程序将取决于此新的承诺是确定还是拒绝。
它可以是异步的,不返回任何内容或返回常规(非承诺)值。 在这种情况下,将启动一个新的异步操作,但是它对当前的诺言链没有影响,因为没有返回与新的异步操作有关的诺言。这个新的异步操作只是按照自己的步调运行,完成后不会对当前的Promise链产生影响。由于没有从.then()
处理程序返回任何承诺,因此当前的承诺会像描述为同步处理程序一样继续进行