我有以下设置,我很好奇这是否是正确的方法。它工作正常,但我只是确保我做得对,或者是否有更好的方法来完成同样的任务。
//custom ajax wrapper
var pageLoadPromise = ajax({
url: //call to webmethod
});
//this is the way I have been doing it
pageLoadPromise.done(cB1)
.done(cB2)
.done(cB3)
.done(cB4)
.done(function(){cB5(args);});
//this function requires that cB1 has been completed
//I tried this and it worked as well
pageLoadPromise.done(cB1,cB2,cB3,cB4)
.done(function(){cB5(agrs)});
两种方式都可行,但就像我说的那样,我想知道这是否是实现这一目标的正确方法?
更新:
我对我的代码做了一些小调整,特别是针对cB1
和回调cB5
pageloadPromise.done(
function(data){
cB1(data).done(function(){
cB5(args);
});
},cB2,cB3,cB4
);
function cB1(data){
var cB1Promise = $.Deferred();
...
cB1Promise.resolve();
return cB1Promise;
}
答案 0 :(得分:0)
正如@Bergi所指出的,无论你如何添加回调,它们都按照它们使用done
附加的顺序运行。因此,promise.done(cb1, cb2, cb3, cb4).done(cb5)
与promise.done(cb1).done(cb2).done(cb3).done(cb4).done(cb5)
相同。
确保在cb5
使用后运行cb1
:
promise.done( function(data) {cb1(data).done(cb5);}, cb2, cb3, cb4);
如果您不需要,请移除data
。
答案 1 :(得分:0)
双向行动
是的,它们几乎相同(除了.done(function(){cB5});
不起作用)。
我想知道这是否是正确的方法来实现这一目标?
使用你更喜欢的那个。这是一个设计问题而不是正确性#34;然而,在我看来,这两种方式看起来很奇怪,而且我已经看到了许多承诺代码。我建议使用两种不同的结构,具体取决于您的应用程序的结构:
您使用pageLoadPromise
作为初始数据的全局缓存。然后,它可以在不同的地方消耗,可能在不同的时间,用于多种不同的事物(或者甚至可能重复地用于同一事物)。然后在每个模块中重复使用pageLoadPromise
:
var pageLoadPromise = ajax({url: …}); // initialisation
pageLoadPromise.done(cB1); // somewhere
…
pageLoadPromise.done(cB2); // somewhere else
…
pageLoadPromise.done(cB3); // other place or time
…
您只在一个地方使用pageLoadPromise
,并且在加载时基本上只做一件事,除了它是由多个子任务构成的;每个只需要一部分,而不是整个结构。然后只使用一个回调:
ajax({url: …}).then(function(data) {
cb1(data.d.cb1data);
cb2(data.d.cb2data);
cb3(data.d.cb3data);
cb4(data.d.cb4data);
cb5(data.d.cb5data, some_additional_data);
});
我对我的代码做了一些小调整,特别是针对
cB1
和回调cB5
如果cb1
没有异步做任何事情,你不应该让它回复。别修改它。如果您想明确表示cb5
需要使用cb1
的结果执行,那么您应该使用.then
进行链接:
var pageLoadPromise = ajax({url: …}); // initialisation
var cB1promise = pageLoadPromise.then(cB1);
cB1promise.done(cb5); // does get called with the return value of cB1
或
ajax({url: …}).then(function(data) {
var res1 = cb1(data.d.cb1data);
…
cb5(data.d.cb5data, some_additional_data, res1);
});
答案 2 :(得分:0)
更新。感谢@Bergi指出jQuery的done()
实际上返回相同的承诺。我已基于此更新了答案。
如果cB2
,cB3
,cB4
没有互连,并且所有这些都处理来自ajax调用的相同数据,那么您可以将它们添加到同一个承诺中{{1 }})。
考虑到上述假设,您的第二个代码版本可以简化,而不需要在cB1()中创建新的承诺,也不必再增加一个缩进级别:
pageloadPromise
这里发生的是pageloadPromise.then(cB1).done(cB5);
pageloadPromise.done(cB2, cB3, cB4);
function cB1(data){
// ...
//data2 would be the argument value passed when resolving
// your original cB1Promise
return data2;
}
调用创建了一个新的promise,可以使用.then()
返回的任何数据来解析,允许cB1
接收该数据而不创建额外的回调并且不涉及另一个承诺(因为我们已经有了一个)。
但是,如果cB5
需要另一个cB1
,那么ajax
的原始实现会更合适(尽管回调计划保持不变)。
最后一点,我没注意到任何失败的处理程序,以防ajax调用失败。