1

我想知道链接 Deferreds 的最佳设计是什么。请考虑以下代码段:

组件 X:

_functionRaisingEvent: function()
{
    $.when(this.raiseEvent('myEvent', args)).done(function(args){ // Check for args.cancel });
},

_raiseEvent: function(event, args)
{
    var def = new $.Deferred();

    // Call subscribers of myEvent in different components and pass them args
    // Subscribers possibly make ajax calls

    return def.promise();
},

订阅者 Y:

_onMyEvent:function(args)
{
    $.ajax(....).done(function(data){ if(data == 1) args.cancel = true;});
},

订阅者 Z:

_onMyEvent:function(args)
{
    document.getElementById('abx').display = 'block';
}

_functionRaisingEvent 调用 _raiseEvent 触发订阅者的回调。

我想要实现的是, _functionRaisingEvent 中的 done 回调仅在所有订阅者完成后执行。

我应该将订阅者自己的 Deferred 作为参数传递并使用管道吗?是否有任何最佳实践或设计模式?

4

1 回答 1

0

关键是改变这部分

_raiseEvent: function(event, args) {
    var def = new $.Deferred();
    //Call subscribers...
    return def.promise();
}

...返回一个延迟集合,而不仅仅是一个,然后将这些作为集合传递给$.when. 由于$.when不接受集合,并且坚持将对象作为单独的参数传递,因此常见的解决方法是通过所有函数继承$.when的方法进行调用。apply()

_raiseEvent: function(event, args) {
    var def = new $.Deferred();
    //Call subscribers... - let's assume each returns an AJAX object
    var result_subscr1 = call_subscriber_1();
    var result_subscr2 = call_subscriber_2();
    return [def.promise(), result_subscr1, result_subscr2];
}

...然后将您的电流更改$.when()

$.when.apply(null, this.raiseEvent('myEvent', args)).done(...

然后将每个延迟的结果done()按照对象传递给的顺序传递给您的回调$.when()

于 2012-06-29T16:08:11.103 回答