你将如何实现1.异步事件队列2.具有事件合并功能



设置:

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

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

问题:

目前,我有一个"队列",它实际上只是将事件反弹到控制器,这是没有帮助的,因为如果当时只有一个事件,我无法比较队列中的两个事件。

那么,我如何确保事件在队列中停留一段时间呢?我想超时功能可以做到这一点,但有更好的方法吗?

为了表扬应该表扬的地方,联合活动的想法受到了Cocoa的启发,我基本上也在尝试做类似的事情。

我对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进行唯一处理。

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

我想超时函数可以做到这一点,但有更好的方法吗?

不,真的没有。

如果您的事件是在同一个运行循环中调度的,那么通常使用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 = [];
}

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

最新更新