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

标签 jquery promise jquery-deferred

我对使用 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/

相关文章:

javascript - 使用 async/await Promise 在 "parallel"中运行 for 循环

jquery - $.当不为我工作时

jquery css3 问题

javascript - JQuery - 搜索 HTML 表格 - rowspan 问题

然后调用Javascript匿名函数

javascript - 捕获 Javascript 返回的 Promise 中的错误

javascript - Reactjs 组件的异步渲染

javascript - 循环内的嵌套 ajax 调用未按顺序执行

javascript - 添加选项以在指定索引处进行选择(使用标签)

具有延迟功能的 jQuery ajax 缓存(当同时触发重复请求时)