我想知道链接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作为参数传递并使用管道吗?是最佳实践或设计模式吗?
答案 0 :(得分: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()
回调。