2

环境:

假设三个事件发生在某个应用程序的三个独立部分中,该事件应由两个控制器处理。应用调度器负责从应用程序的所有部分发送/接收事件,并且这个调度器应该有一个异步事件队列。

在某些情况下,三个事件中的两个与某个属性相关但名称不同,只有一个应该传递给控制器​​,另一个可能会被丢弃。

问题:

目前,我有一个“队列”,它实际上只是将事件反弹到控制器,这无济于事,因为如果队列中只有一个事件,我无法比较队列中的两个事件。

那么如何确保事件应该在队列中停留一段时间呢?我想超时功能可以解决问题,但有更好的方法吗?

值得称赞的是,合并事件的想法是受到 Cocoa 的启发,我基本上是在尝试做类似的事情。

4

2 回答 2

2

我对 Cocoa 了解不多,但我假设它会用最新事件替换旧事件,直到事件能够被分派给应用程序(即,如果应用程序由于某种原因忙)。我不确定您的特定用例是什么,但是如果您想对事件进行速率限制,我会这样使用setTimeout

function Dispatcher(controllers) {
    this.controllers = controllers;
    this.events = [];
    this.nextController = 0;
}
Dispatcher.prototype = {
    _dispatch: function (i) {
        var ev = this.events.splice(i, 1);
        this.controllers[this.nextController].handle(ev);
        this.nextController = (this.nextController + 1) % this.controllers.length;
    },
    notify: function (ev) {
        var index = -1, self = this, replace;

        function similer(e, i) {
            if (e.type === ev.type) {
                index = i;
                return true;
            }
        }

        replace = this.events.some(similar);
        if (replace) {
            this.events[i] = ev;
        } else {
            // it's unique
            index = this.events.push(ev) - 1;
            setTimeout(function () {
                self._dispatch(index);
            }, 100);
        }
    }
};

只需调用notify事件(确保有type属性或类似属性),它就会处理魔法。不同类型的事件将用自己的setTimeout.

我还没有测试过这段代码,所以可能有错误。

于 2012-12-05T21:33:11.767 回答
1

我想超时功能可以解决问题,但有更好的方法吗?

不,真的没有。

setTimeout(..., 0)如果您的事件在同一个运行循环中分派,通常要使用的方法是使用。所以实现看起来像这样:

var eventQueue = [];
var handlerTimer = -1;
function fireEvent(event, params) {
    eventQueue.push([event, params]);
    window.clearTimeout(handlerTimer);
    handlerTimer = window.setTimeout(resolveQueue, 0);
}

function resolveQueue() {
    // process eventQueue and remove unwanted events...
    // then dispatch remaining events

    eventQueue = [];
}

如果您需要处理来自不同运行循环的事件(例如mouseup和之类的本机事件click),则需要使用 0 以外的超时值。确切的值取决于您希望累积事件的时间。

于 2012-12-05T21:26:05.753 回答