gpt4 book ai didi

jQuery:按顺序执行函数数组(延迟和非延迟)

转载 作者:行者123 更新时间:2023-11-30 23:47:08 30 4
gpt4 key购买 nike

我对使用 Promises 还很陌生,并且很难理解 jQuery deferreds。

我目前拥有的是在某个点执行的一组函数:

while (queue.length) {
(queue.shift())();
}

这样做的问题是,其中一些函数是异步的,但我需要它们一个接一个地运行。

因此,队列中的某些函数返回延迟函数(例如通过 jQuery.ajax()),而有些函数只是普通函数。我想知道是否可以按顺序执行它们(仅当前一个函数完成时才执行下一个函数)。

我想也许 jQuery.when 就是我正在寻找的,但我不知道到底如何做,我只是想到了这个:

var deferred = jQuery.Deferred();
while (queue.length > 0) {
deferred.done().then(queue.shift());
}

最佳答案

非常精明,jQuery.when 就是您正在寻找的东西。它接受一个 Promise 或一个普通的 non-thenable 并返回一个超过该值的 Promise。但是,由于这里有函数而不是值,所以这并不是真正需要的,因为无论如何这是 .then 的行为。

var queue = [syncFunction, syncFunc2, returnsPromiseAsync];

var d = $.Deferred().resolve();
while (queue.length > 0) {
d = d.then(queue.shift()); // you don't need the `.done`
}

( fiddle )

或者,您可以减少;

var res = queue.reduce(function(prev,cur){ // chain to res later to hook on done
return prev.then(cur);
}, $.Deferred().resolve());

如果您有更多代码在下面执行操作,由于队列中的函数可能同步或异步运行(或者某些同步,然后我们遇到异步),为了避免困惑,您可能需要确保函数始终运行异步地。您可以通过将 resolve 包装在 setTimeout 中的初始 Deferred 上轻松实现此目的:

var p = $.Deferred();
var res = queue.reduce(function(prev,cur){ // chain to res later to hook on done
return prev.then(cur);
}, p);
setTimeout(p.resolve.bind(p), 0);

现在,直到超时发生为止,该进程不会启动,并且此后的任何代码肯定会在队列中的第一个函数执行之前运行。在我看来,这与 jQuery promise 的语义不一致(因为 they are inconsistent about sync vs. async callbacks ),但您可能需要一致性。

如果您需要知道进程何时完成,只需在 res 上使用 .then 处理程序即可:

res.then(function() {
// All functions have now completed
});

对于这些情况,这里有一个简单的包装函数,可以同时执行这两种操作:

function clearQueue(q) {
var p = $.Deferred();
setTimeout(p.resolve.bind(p), 0);

return q.reduce(function(prev,cur){
return prev.then(cur);
}, p);
}

使用示例(fiddle):

clearQueue(queue).then(function() {
console.log("All done");
});
console.log("This runs before any queued function starts");

关于jQuery:按顺序执行函数数组(延迟和非延迟),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24931115/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com