3

在我的 jQuery Web 应用程序中,我使用的事件非常多。
我对服务器执行 ajax 客户端请求(名称为“comm”)的组件有一个队列。
此队列类似于 Backbone.js 集合。

因此,每次我将一个新的请求对象放入“comm”的集合时,comm 对象都会收到一个“add”事件,并且“comm”的“worker”方法会查看当前是否有正在进行的请求。如果没有人,worker 方法会处理请求,最后,当一切正常时,会在请求对象上触发“完成”事件。

在此通信组件中,一次只能有一个请求。如果我将一个请求对象添加到“comm”并且“add”事件被触发并且工作方法看到已经有一个请求,那么什么都不会发生。

我的问题是:在这种情况下,对于“事件基础设施”,处理这个未处理的请求对象的最佳方法是什么?

到目前为止,我有两种不同的方法:

1)我可以做以下事情:如果我正在进行的请求完成了,worker方法可以检查集合中是否有未处理的请求对象并处理它。这很简单,不涉及任何事件。

2) 或者不同的东西:如果工作方法由于“添加”事件而启动并且看到已经有一个正在进行的请求,我可以实现类似:“我无法充分响应这个添加事件,我把你放回去.请在200毫秒后再次触发自己,也许我有时间。”

也许有人已经遇到过类似的问题并且对此有很好的解决方案?

4

2 回答 2

2

我认为解决这个问题的一个好方法是实现在队列上触发的“下一个”事件。每次触发“完成”事件时,它应该触发队列​​中的下一个事件,然后查看是否有任何未处理的请求,如果有,则根据您的逻辑选择一个(我假设 FIFO)

于 2013-02-07T10:56:51.757 回答
0

如果我理解你是正确的,你想链接请求或其他异步事件吗?那么promises模式是一个优雅的解决方案。

JQuery 已经用Deferred 对象实现了它。

使用 JQuery 1.8+,请求链接可以很简单:

$.ajax(...).then(
    function() {
        return $.ajax(...);
    }
).then(
    function() {
        return $.ajax(...);
    }
);

但是你也可以围绕它构建一个更加动态和复杂的架构。例如,您可以实现您的队列,使其始终存储最后一个未解决的承诺,以便您可以在它已经处于活动状态时将新的处理程序附加到它。

通用示例:

var Queue = function() {
    // start with resolved promise
    var promise = $.Deferred().resolve();

    this.add = function(handler) {
        // chain and replace latest with next promise
        promise = promise.then(function() {
            var deferred = $.Deferred();
            handler(deferred);
            return deferred;
        }).promise();
    }
};

var q = new Queue();
q.add(function(deferred) {
    setTimeout(function() { alert('handler 1'); deferred.resolve(); }, 1000);
});
q.add(function(deferred) {
    setTimeout(function() { alert('handler 2'); deferred.resolve(); }, 1000);
});

JSFiddle 演示

在这里,处理程序获取一个延迟对象作为参数,如果它们“完成”,则负责解决(或拒绝)它。另一种更灵活的可能性是处理程序必须自己创建延迟对象并返回其承诺,这样您也可以使用其他承诺,例如 $.ajax 返回的承诺

于 2013-02-07T10:34:02.633 回答