2

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

在我的搜索中,我遇到了 Promises 的想法,但这似乎比我需要的要多。

我明白了一般原则 - 你有一个使用 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
}

其中回调始终是第一个参数,因此可以附加任意数量的其他参数。但就像我说的那样,我很难把我的大脑包裹在这一切上,所以一个彻底的解释/任何替代方案将不胜感激!

编辑

我想出的队列可以在我的后续问题中找到。

4

1 回答 1

3

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

确切地。

这就是Promises的概念——您的动画函数返回一个对象,队列可以在该对象上附加“完成”侦听器。如果您不想使用众多库之一,您也可以实现自己的系统(一个简单的 pub-once/sub-often 模式)。看看如何实现 promise/defer 库?(尤其是我答案的 两个修订版)以获得一些灵感……</p>

然后队列将像

var promise = queue[i].fn.apply(null, queue[i].args);
promise.then(function() {
    i++;
    // … "recurse"
});

b) 可以接受来自队列的回调吗?这会更容易,看起来像: function name(callback, param1, param2, ... paramX) {…}回调始终是第一个参数,因此可以添加任意数量的其他参数。

确切地。还是最后一个参数,比较常见。查看用于调用具有动态数量参数的函数的applyFunction 方法。

队列将类似于

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
}

但就像我说的那样,我很难把我的大脑包裹在这一切上,所以一个彻底的解释/任何替代方案将不胜感激!

好吧,您已经掌握了它 - 除了您概述的两种方法之外,没有其他选择。Promise 方法更可靠,更适用于动画函数的可变参数,而回调方法更简单。

于 2013-08-22T18:08:00.850 回答