API 设计:如何合并两个延迟 jQuery 对象的结果?
API design: How can I combine result of two deferred jQuery objects?
假设我能够独立地获取($.ajax
)、处理(process_*
)和保存(store_* =
)数据A
和B
有 API:
var store_A;
function A() {
$.ajax({url: "/getA"}).done(function(data) {
store_A = process_A(data);
}); }
var store_B;
function B() {
$.ajax({url: "/getB"}).done(function(data) {
store_B = process_B(data);
}); }
我有一个函数 C()
可以将 store_A
和 store_B
组合成一些东西:
var store_C;
function C() {
store_C = process_C(store_A, store_B);
}
假设 A()
、B()
和 C()
是 public API 并且所有其他内容都是内部结构并且实际上是复杂代码(例如我不能直接链接 $.ajax
)。
我想通过使用 jQuery Deferred API 将上面的代码重构为新的 API,这样我就可以请求任何情况:
case1: after(A).do(C)
case1: after(B).do(C)
case2: afterParallelJobsFinished(A, B).do(C)
并确保store_A
或store_B
按要求更新,store_C
仅在A/B中的一个或两个按要求更新后才更新。
假设我们有 web 应用程序,用户可以在其中管理一组收入和支出。
在页面加载时,我们从不同的数据源(即 $.ajax
)并行获得收入和支出,呈现视图和存储数据(通常是混合的process_*
/ store_* =
) 并在所有数据到达时显示 total = SUM(incomes) - SUM(expenses)
.
也就是case2
.
当用户编辑费用并请求部分页面更新时,我们在 case1
因为我们只需要 load/render/store 扩展来获得正确的 total = SUM(incomes) - SUM(expenses)
。
$.when()
可以接受任意数量的延迟对象。 It can even take a dynamic number 如果你不知道你会打多少电话。
$.when(callA(), callB()).done(function() {
// Do stuff here when both calls are done
});
function callA() {
return $.ajax({
url: ...,
success: function() {
// Do stuff here when callA is done
}
});
}
function callB() {
return $.ajax({
url: ...,
success: function() {
// Do stuff here when callB is done
}
});
}
现在,当我熟悉jQuery.Deffered
API我想添加一些更多的自我表达的例子:
function callA() {
return $.ajax({ url: ... })
.done(function(data) { successA(data); })
.fail(function(data) { failA(data); });
}
function callB() {
var promise1 = $.ajax({ url: ... })
.done(function(data) { succB_1(data); })
.fail(function(data) { failB_1(data); });
var promise2 = $.ajax({ url: ... })
.done(function(data) { succB_2(data); })
.fail(function(data) { failB_2(data); });
return $.when(promise1, promise2)
.done(function(data1, data2) { succCombined(data1, data2); })
.fail(function(data1, data2) { failCombined(data1, data2); });
}
$.when(callA(), callB()).done(function() {
// Do stuff here when both calls are done
});
注意在callA
/callB
里面我使用data
/data1
/data2
因为我知道内部API协议。在最后几行中,我不认为 callA
/callB
return 是明智的。但是如果我将 public API 添加到 callA
/callB
我可以使用:
$.when(callA(), callB()).done(function(resultA, resultB) {
// Do stuff here when both calls are done
});
这是对 Matthew Herbst 仅坚持 Promise 逻辑的回答的修订。这避免了混合 Promise 逻辑和 ajax success:
回调造成不必要的混淆。
$.when(callA(), callB()).done(function() {
// Do stuff here when both .then()'s are complete
});
function callA() {
return $.ajax({
url: ...,
}).then(function(result){
// Do something when callA finishes
return result;
});
}
function callB() {
return $.ajax({
url: ...,
}).then(function(result){
// Do something when callB finishes
return result;
});
}
假设我能够独立地获取($.ajax
)、处理(process_*
)和保存(store_* =
)数据A
和B
有 API:
var store_A;
function A() {
$.ajax({url: "/getA"}).done(function(data) {
store_A = process_A(data);
}); }
var store_B;
function B() {
$.ajax({url: "/getB"}).done(function(data) {
store_B = process_B(data);
}); }
我有一个函数 C()
可以将 store_A
和 store_B
组合成一些东西:
var store_C;
function C() {
store_C = process_C(store_A, store_B);
}
假设 A()
、B()
和 C()
是 public API 并且所有其他内容都是内部结构并且实际上是复杂代码(例如我不能直接链接 $.ajax
)。
我想通过使用 jQuery Deferred API 将上面的代码重构为新的 API,这样我就可以请求任何情况:
case1: after(A).do(C)
case1: after(B).do(C)
case2: afterParallelJobsFinished(A, B).do(C)
并确保store_A
或store_B
按要求更新,store_C
仅在A/B中的一个或两个按要求更新后才更新。
假设我们有 web 应用程序,用户可以在其中管理一组收入和支出。
在页面加载时,我们从不同的数据源(即 $.ajax
)并行获得收入和支出,呈现视图和存储数据(通常是混合的process_*
/ store_* =
) 并在所有数据到达时显示 total = SUM(incomes) - SUM(expenses)
.
也就是case2
.
当用户编辑费用并请求部分页面更新时,我们在 case1
因为我们只需要 load/render/store 扩展来获得正确的 total = SUM(incomes) - SUM(expenses)
。
$.when()
可以接受任意数量的延迟对象。 It can even take a dynamic number 如果你不知道你会打多少电话。
$.when(callA(), callB()).done(function() {
// Do stuff here when both calls are done
});
function callA() {
return $.ajax({
url: ...,
success: function() {
// Do stuff here when callA is done
}
});
}
function callB() {
return $.ajax({
url: ...,
success: function() {
// Do stuff here when callB is done
}
});
}
现在,当我熟悉jQuery.Deffered
API我想添加一些更多的自我表达的例子:
function callA() {
return $.ajax({ url: ... })
.done(function(data) { successA(data); })
.fail(function(data) { failA(data); });
}
function callB() {
var promise1 = $.ajax({ url: ... })
.done(function(data) { succB_1(data); })
.fail(function(data) { failB_1(data); });
var promise2 = $.ajax({ url: ... })
.done(function(data) { succB_2(data); })
.fail(function(data) { failB_2(data); });
return $.when(promise1, promise2)
.done(function(data1, data2) { succCombined(data1, data2); })
.fail(function(data1, data2) { failCombined(data1, data2); });
}
$.when(callA(), callB()).done(function() {
// Do stuff here when both calls are done
});
注意在callA
/callB
里面我使用data
/data1
/data2
因为我知道内部API协议。在最后几行中,我不认为 callA
/callB
return 是明智的。但是如果我将 public API 添加到 callA
/callB
我可以使用:
$.when(callA(), callB()).done(function(resultA, resultB) {
// Do stuff here when both calls are done
});
这是对 Matthew Herbst 仅坚持 Promise 逻辑的回答的修订。这避免了混合 Promise 逻辑和 ajax success:
回调造成不必要的混淆。
$.when(callA(), callB()).done(function() {
// Do stuff here when both .then()'s are complete
});
function callA() {
return $.ajax({
url: ...,
}).then(function(result){
// Do something when callA finishes
return result;
});
}
function callB() {
return $.ajax({
url: ...,
}).then(function(result){
// Do something when callB finishes
return result;
});
}