Javascript 为什么then()链式方法不按顺序运行?

Javascript 为什么then()链式方法不按顺序运行?,javascript,jquery,ajax,promise,Javascript,Jquery,Ajax,Promise,我们正试图以特定的顺序执行大量AJAX调用。下面的代码包含methodA、methodB和methodC,它们分别返回一个运行async=true的AJAX promise对象 它们使用jQuery中的then函数链接 我做了一个慢方法B我使用一个慢URL 我期待一个。。。10秒等待…然后是B然后是C 相反,我得到了A,C…10秒的等待和B 它为什么这样做?这与我在always函数中使用警报有关吗 下面是我的代码: 代码: 简明扼要: this.save = function() {

我们正试图以特定的顺序执行大量AJAX调用。下面的代码包含methodA、methodB和methodC,它们分别返回一个运行async=true的AJAX promise对象

它们使用jQuery中的then函数链接

我做了一个慢方法B我使用一个慢URL

我期待一个。。。10秒等待…然后是B然后是C

相反,我得到了A,C…10秒的等待和B

它为什么这样做?这与我在always函数中使用警报有关吗

下面是我的代码:

代码:

简明扼要:

this.save = function() {
    self.methodA().then( self.methodB ).then( self.methodC )
}
@meagar是对的,而我在这一点上错了,这一天一直困扰着我,但我确信我是对的。他的回答似乎太复杂了,但早上我头脑模糊,我的回答也不对。这是正确的答案,当您将其插入JSFIDLE时,它可以完美地工作。

简短而简单:

this.save = function() {
    self.methodA().then( self.methodB ).then( self.methodC )
}
@meagar是对的,而我在这一点上错了,这一天一直困扰着我,但我确信我是对的。他的回答似乎太复杂了,但早上我头脑模糊,我的回答也不对。这是正确的答案,当您将其插入JSFIDLE时,它可以完美地工作。

这是错误的:

self.methodA().then( self.methodB() ).then( self.methodC() )
您将立即调用每个方法,并将承诺传递到

如果希望每个函数等待前一个函数完成,则需要为每个函数提供一个回调,以便在前一个承诺解析时执行:

self.methodA().then(function () { return self.methodB() }).then(function() { return self.methodC() });
这是错误的:

self.methodA().then( self.methodB() ).then( self.methodC() )
您将立即调用每个方法,并将承诺传递到

如果希望每个函数等待前一个函数完成,则需要为每个函数提供一个回调,以便在前一个承诺解析时执行:

self.methodA().then(function () { return self.methodB() }).then(function() { return self.methodC() });

当你只需要编辑parantises:self.methodA.thenself.methodB.thenself时,不需要创建空函数。methodC@L3viathan是的,有。你的方式被打破了,methodB和methodC不会有正确的方法。请原谅我天真的想法:但我的“非包装”版本不会也会给你一个承诺吗?或者承诺被作为一个参数传递到了那个时候。但是是的,你的版本是有效的。@OliverWatkins是的,它传递了对当时的承诺,但那不是当时的目的。然后期待回调,而回调本身可能会返回一个承诺。这就是使用它的全部意义所在。否则,您将同时调用所有三个方法A、B和C,它们将以任意顺序解析,主要取决于每个请求所需的时间。如果这是你的目标,那么你根本不需要,你想要什么时候。但是,如果您希望请求按顺序开始和完成,则需要我提供的thenfunction{…}行。@Oliver Watkins实际上,您已经有了返回承诺的函数,它们被称为methodB和methodC。所以我们可以直接使用这些函数作为对象,然后调用。这是一个更短、更简单的解决方案,因为它不会向混合中添加额外的不必要的函数包装集。请参阅我的更正答案,了解最简单的解决方案。当您只需使用parantises:self.methodA.thenself.methodB.thenself时,无需创建空函数。methodC@L3viathan是的,有。你的方式被打破了,methodB和methodC不会有正确的方法。请原谅我天真的想法:但我的“非包装”版本不会也会给你一个承诺吗?或者承诺被作为一个参数传递到了那个时候。但是是的,你的版本是有效的。@OliverWatkins是的,它传递了对当时的承诺,但那不是当时的目的。然后期待回调,而回调本身可能会返回一个承诺。这就是使用它的全部意义所在。否则,您将同时调用所有三个方法A、B和C,它们将以任意顺序解析,主要取决于每个请求所需的时间。如果这是你的目标,那么你根本不需要,你想要什么时候。但是,如果您希望请求按顺序开始和完成,则需要我提供的thenfunction{…}行。@Oliver Watkins实际上,您已经有了返回承诺的函数,它们被称为methodB和methodC。所以我们可以直接使用这些函数作为对象,然后调用。这是一个更短、更简单的解决方案,因为它不会向混合中添加额外的不必要的函数包装集。请参阅我的更正答案,以获得最简单的解决方案。将“返回”放在其中会给我带来未可知的SyntaxError:意外的令牌返回这是如何上浮4次的?这是完全错误的。它甚至在语法上都不正确@OliverWatkins社区没有很好地为你整理这个案例的答案。你的新答案仍然是错误的。看看methodB和methodC的实现。第一行是var self=this,方法依赖于此上存在的某些属性。您的新代码将methodB和methodC与se分离
lf,并且由于其实施而无法工作。在严格模式下,这将是window或null,因此您的代码将失败。@meagar是的,您完全正确。您应该删除另外三行,以获得更简单的版本。由于self是在外部范围中定义的,因此方法A、B和C都可以看到它。因此,从每个方法中删除var self=this,就不会出现范围混淆。在这里,它是在一个单一的小提琴,工作得很好:注意:我换了,因为appspot不处理CORS,所以我们在B调用上得到了一个错误。把'返回'放在那里给我未可知的Syntaxer错误:意外的令牌返回这是怎么投票4次?这是完全错误的。它甚至在语法上都不正确@OliverWatkins社区没有很好地为你整理这个案例的答案。你的新答案仍然是错误的。看看methodB和methodC的实现。第一行是var self=this,方法依赖于此上存在的某些属性。您的新代码将methodB和methodC与self分离,并且在给定其实现的情况下无法工作。在严格模式下,这将是window或null,因此您的代码将失败。@meagar是的,您完全正确。您应该删除另外三行,以获得更简单的版本。由于self是在外部范围中定义的,因此方法A、B和C都可以看到它。因此,从每个方法中删除var self=this,就不会出现范围混淆。在这里它是在一个单一的小提琴,工作得很好:注意:我换了,因为appspot不处理CORS,所以我们得到了一个错误的B调用。