问题描述
我希望函数A完成执行,并且只有在函数B开始执行之后才能执行。当我调用函数A然后调用函数B时,它们似乎都在同时执行。在函数B完成后,我想调用第三个函数update_dropdown()。
I want function A to finish execution and only after that function B should start executing. When I call function A and then function B, it seems both are executing simultaneously. And after function B completes, I want to call a third function update_dropdown().
我的代码如下所示:
function A {
for (var i = 0; i < 5; i++) {
var promise = $.get(url+i);
$.when(promise).then(function () {
$.post(url);
});
}
}
function B {
var x = $.get(url);
var promise = $.post(url+x);
$.when(promise0).then(function () {
update_dropdown();
});
}
请告诉我如何按顺序进行这3个函数调用。
Please can you tell me how I can make these 3 function calls happen sequentially.
推荐答案
好的,你真正想要的更清楚一点(基于你最近的评论来解决澄清问题)仍然至少有两个选项打开。
OK, it's getting a little bit clearer what you actually want (based on your recent comments to address clarifying questions) though there are still at least two options open.
对于这样的操作,您可能希望利用许多承诺功能:
For an operation like this, you probably want to take advantage of a number of promise features:
- jQuery的Ajax调用已经返回一个承诺,所以你可以直接使用它们
- 要序列化操作,你可以链接多个promise操作
- 要使异步操作序列化正确,您可以从
.then()
处理程序返回一个承诺,主承诺将解决只有当所有链接的承诺都已解决时(内置的$。when()
,而不必显式调用$。when()
)。 - 您可以根据需要将多个操作链接在一起,主承诺会告诉您何时完成这些操作。
- 我如果您从
A()
和B()
返回承诺,那么这些函数的调用者可以监视它们何时使用promise方法完成,然后让你链接A()。然后(B)
对这两个进行排序。 - 当你排序时使用链接的操作,先前的方法解析数据被传递到链中的下一个
.then()
处理函数作为的第一个参数。然后()
处理函数所以如果您需要先前的数据用于下一个操作,它就可以使用。
- jQuery's Ajax calls already return a promise so you can just use those directly
- To serialize operations, you can just chain multiple promise operations together
- To make async operations serialize properly, you can return a promise from a
.then()
handler and the master promise will resolve only when all the chained promises have resolved (kind of a built-in$.when()
without having to explicitly call$.when()
). - You can chain as many operations together as you want and the master promise will tell you when they are all done.
- If you return promises from both
A()
andB()
, then the callers of those functions can monitor when they are done with promise methods which then lets you chainA().then(B)
to sequence those two. - When you sequence operations with chaining, the prior methods resolve data is passed to the next
.then()
handler function in the chain as the first argument to the.then()
handler function so if you need the prior data for the next operation, it is right there to use.
因此,利用所有这些功能,只需在代码周围放置正确的脚手架即可实现您想要的精确顺序。以下是两个不同的选项:
So, with all those capabilities, it's just a matter of putting the right scaffolding around the code to implement the exact sequencing you want. Here are two different options:
选项1:如果要序列化 A()
以便所有10个请求以串行方式发生(下一个请求只在前一个请求完成时继续),然后它看起来像这样:
Option 1: If you want to serialize everything in A()
so that all 10 requests happen in serial fashion (the next one proceeds only when the prior one is done), then it could look like this:
// serialize all requests
function A() {
var p = $.get(url).then(function(data) {return $.post(url)});
for (var i = 1; i < 5; i++) {
// chain four more pairs of requests onto the original promise
p = p.then(function() {return $.get(url)})
.then(function(data) {return $.post(url)});
}
// return the promise so callers can monitor when A() is done
return p;
}
function B() {
// sequence these three operations one after the other
return ($.get(url)
.then(function(data) {return $.post(url + x)})
.then(update_dropdown)
);
}
// run them both, one after the other
A().then(B);
选项2:如果你希望 A()
中的5对请求并行运行,只有的最后一部分A()
等到5对请求完成后,它可能如下所示:
Option 2: If you want the 5 pairs of requests in A()
to run in parallel, with only the last part of A()
waiting until the 5 pairs of requests are done, then it could look like this:
// parallelize pairs of requests
function A() {
var promises = [];
for (var i = 0; i < 5; i++) {
// execute 5 pairs of requests where each pair is serialized in itself
promises.push($.get(url).then(function(data) {return $.post(url)}));
}
// return a promise that resolves only when all the other promises are done
return $.when.apply($, promises);
}
function B() {
// sequence these three operations one after the other
return ($.get(url)
.then(function(data) {return $.post(url + x)})
.then(update_dropdown)
);
}
// run them both, one after the other
A().then(B);
如果您从 .then返回承诺,则使用这个概念( )
处理程序函数,然后它将多个异步操作链接在一起,并且仅在解析所有链接操作时解析主提示。这对于对多个ajax操作进行排序非常有用,你甚至可以像你一样在循环中进行操作。
These use the concept that if you return a promise from a .then()
handler function, then it will chain multiple async operations together and the master promise is only resolved when all the chained operations are resolved. This is very powerful for sequencing multiple ajax operations and you can even do it for operations in a loop like you have.
这篇关于javascript中的顺序函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!