等待异步事件处理程序的设计模式

时间:2014-04-30 16:03:32

标签: javascript design-patterns asynchronous promise

我的应用程序中有一些地方,一个对象应该发出一个事件,并且应该延迟执行,直到所有事件处理程序都完成了工作。 事件处理程序可能正在执行异步操作(例如,写入数据库)。

Application.on("login", function(evt) {
    // Asynchronous operation (e.g. update info in database)
});

Application.trigger("login").then(function() {
    // Execute stuff after all (async) event handlers are done
});

我环顾四周,并没有找到任何既定的设计模式。我有一个我很满意的实施,但我很好奇是否有人以不同的方式解决了这个问题?

1 个答案:

答案 0 :(得分:1)

我的解决方案是在promises[]参数中添加evt属性。异步事件回调只是为这个数组添加一个promise,triggerAsync函数返回一个等待所有promises结算的promise。

http://jsfiddle.net/nonplus/9aCC4/

triggerAsync 方法的实现(使用Backbone事件和jQuery promise,但也适用于其他堆栈):

// Trigger an event and return promise that waits on
// event handler promises
function triggerAsync(emitter, name, evt) {
    evt || (evt={});
    evt.promises = [];
    emitter.trigger(name, evt);
    return $.when.apply(null, evt.promises);
}

使用triggerAsync:

triggerAsync(obj, "myEvent").then(function() {
    // Code executed after event handlers are done
});

异步事件处理程序的实现:

// Async handler doing an ajax request
obj.on("myEvent", function (evt) {
    evt.promises.push($.ajax(...));
});

// Async handler doing generic async operation
obj.on("myEvent", function (evt) {
    var dfd = $.Deferred();
    evt.promises.push(dfd.promise());

    // Async operation
    // Eventually calls dfd.resolve() or dfd.reject()
});