当前位置:  开发笔记 > 编程语言 > 正文

同步函数和异步延迟jQuery对象的混合

如何解决《同步函数和异步延迟jQuery对象的混合》经验,为你挑选了1个好方法。

我想发送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)

fakeResolvedPromiseWrapperAroundSyncFuncjQuery库中有任何标准解决方案吗?

在启动异步并随后加入异步调用的结果之后,还有其他路径来运行同步代码吗?



1> jfriend00..:

.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()处理程序返回任何承诺,因此当前的承诺会像描述为同步处理程序一样继续进行

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有