【问题标题】:Design pattern for waiting on asynchronous event handlers等待异步事件处理程序的设计模式
【发布时间】:2014-04-30 16:03:31
【问题描述】:

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

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
});

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

【问题讨论】:

  • 你看到了吗:Trigger custom event Synchronously
  • @DavidTansey:那里提出的解决方案似乎都不起作用
  • @Bergi 是正确的。 jQuery的触发器是同步操作。

标签: javascript design-patterns asynchronous promise


【解决方案1】:

我的解决方案是将promises[] 属性添加到evt 参数。异步事件回调只需向该数组添加一个 Promise,triggerAsync 函数返回一个等待所有 Promise 解决的 Promise。

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

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

// 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()
});

【讨论】:

  • 只是好奇,为什么使用evt = _.extend({promises: []}, evt); 而不是evt.promises = [];
  • 这样可以避免修改传入的 evt 对象,如果 evt 参数未定义也可以。
  • 但是,如果未定义,我可以初始化 evt,然后简单地分配 promises 属性。
  • 如果您的答案不依赖于下划线,它可能对更多人有用。此外,在您的异步事件处理程序示例中,最好显示一个 ajax 调用,您可以在其中使用已经返回的承诺,而不是创建自己的延迟,因为这可能是最常见的异步操作并且您已经需要jQuery.
  • 当我看到evt || (evt={}); 时,我做了双重考虑,因为我以前没有见过这种模式。我已经习惯看到它像evt = evt || {};
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
相关资源
最近更新 更多