Javascript:如何实现异步函数队列(无库)

Javascript:如何实现异步函数队列(无库),javascript,animation,asynchronous,callback,Javascript,Animation,Asynchronous,Callback,我一直在搜索谷歌等等,但出于某种原因,我很难将我的大脑集中在这上面。只是强调一下,我不想加载像JQuery这样的库,因为我不需要它的大部分。虽然我可以使用动画库,但我已经构建了我自己需要的一些功能(其中一些甚至不是库中的标准动画),所以我不确定这些功能是否有用。事实上,我可以很容易地将这个问题命名为“如何-异步函数队列”,因为它不是特定于动画的 在我的搜索中,我偶然发现了承诺的概念,但这似乎比我需要的要多一些 我了解了一般原理-您有一个使用setInterval/setTimeout的异步函数,

我一直在搜索谷歌等等,但出于某种原因,我很难将我的大脑集中在这上面。只是强调一下,我不想加载像JQuery这样的库,因为我不需要它的大部分。虽然我可以使用动画库,但我已经构建了我自己需要的一些功能(其中一些甚至不是库中的标准动画),所以我不确定这些功能是否有用。事实上,我可以很容易地将这个问题命名为“如何-异步函数队列”,因为它不是特定于动画的

在我的搜索中,我偶然发现了承诺的概念,但这似乎比我需要的要多一些

我了解了一般原理-您有一个使用setInterval/setTimeout的异步函数,并且在给定正确的条件下,清除间隔(如果适用)并运行回调:

function callback() {
    alert('It was just a sales call... Now where were we?');
}
function anim() {
    var i = 0,
        interval = setInterval( function() {
            // do something with the current value of i
            if (i === 100) {
                clearInterval( interval );
                callback();
            }
            i++;
        }, 50);
}
当然,如果通过将'callback'作为anim()的参数,使其可重用,这会更好。然而,我真正想做的是:

var populateDialog = new Queue([
    {fn: anim, args: ['height','300px',1500]},
    {fn: type, args: [input.value, outputDiv]},
    {fn: highlight}
]);
populateDialog.start();
将调用第一个函数,完成后,将调用队列数组中的下一项。问题是,虽然队列本身可以很容易地按顺序调用函数,但在继续之前,它需要知道当前函数的状态何时为“完成”

我需要如何设计要添加到队列中的任何函数,以使其a)发布其状态(以及如何让队列检测到该状态?)或b)可以接受来自队列的回调?我猜前者会涉及某种定制事件系统,后者会更容易,看起来像:

function name(callback, param1, param2, ... paramX) {
    // setTimeout or setInterval some stuff, then call the callback argument
}
其中回调始终是第一个参数,因此可以附加任意数量的其他参数。但正如我所说,我真的很难把所有这些都用在脑子里,所以如果能提供一个彻底的解释/任何其他选择,我将不胜感激

编辑

我排的队可以在

我需要如何设计我想添加到队列中的任何函数,以便它发布其状态(以及我如何让队列检测到它?)我猜这将涉及某种自定义事件系统

没错

这就是-your animation函数的概念,它返回一个对象,队列可以在该对象上附加“done”侦听器。如果您不想使用其中一个,还可以实现您自己的系统(一个简单的pub once/sub-frequency模式)。看一看(特别是我的答案的修改)以获得一些启示

然后,队列将像这样工作

var promise = queue[i].fn.apply(null, queue[i].args);
promise.then(function() {
    i++;
    // … "recurse"
});
b) 是否可以接受队列中的回调?这会更容易,看起来像:
函数名(callback,param1,param2,…paramX){…}
其中,回调始终是第一个参数,因此可以附加任意数量的其他参数

没错。或者最后一个参数,更常见。请看一看使用动态参数数调用函数的示例

队列将类似于

function step(i) {
    function callback() {
        step(i+1); // "recurse"
    }
    if (i < queue.length)
        queue[i].fn.apply(null, queue[i].args.concat(callback));
    // else: all done
}
功能步骤(i){
函数回调(){
步骤(i+1);/“递归”
}
if(i
但正如我所说,我真的很难把所有这些都用在脑子里,所以如果能提供一个彻底的解释/任何其他选择,我将不胜感激


嗯,你已经搞定了——除了你概述的两种方法之外,没有其他选择。promise方法更可靠,更适用于动画函数的可变参数,而回调方法更简单。

是的,我意识到回调通常是最后一个参数,这就是为什么首先让我感到奇怪的原因。您能否编辑您的答案,以显示我需要如何让每个功能访问该功能?我知道如何使用apply——我可以轻松地将回调添加到参数数组中。我是否需要访问参数和.pop()最后一项(回调)?此外,我还确定了概念。我理解这一切背后的概念。我似乎无法将其转化为实际代码!呵呵。两种方法中哪一种更好?赞成和反对。。。哪个更容易?老实说,承诺这个想法让我很困惑。不管我读了多少遍关于它的各种文章,我都没能弄明白那个笨蛋!谢谢你的补充解释,尽管我仍然不知道如何真正实现它,直到我坐下来自己弄明白了。查看我编辑的帖子,看看我是否很好地实现了它。哦,好的。。。我不知道我应该这么做。正如这篇文章的标题所暗示的,我想要一个关于排队的完整操作方法,因为我在其他地方很难找到它。虽然你的回答让我如愿以偿,但我觉得这还不够。仍然有足够的纠结来解决我所发布的内容,我觉得它仍然适合在“操作”标题下。如果你真的认为我应该开始一个新问题,我可以这样做。是的,我认为你的新问题基本上是不同的。虽然可能是在同一主题上,但问题风格已经发生了巨大的变化(从“如何设计队列”、“如何进行回调”到“我的代码是否存在问题”和“队列应该具有哪些功能”)。