API 设计:如何组合两个延迟 jQuery 对象的结果

API design: How can I combine result of two deferred jQuery objects?

本文关键字:延迟 两个 jQuery 对象 结果 何组合 设计 API 组合      更新时间:2023-09-26

假设我能够独立获取($.ajax(,处理(process_*(和保存(store_* =(数据AB并且已经有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_Astore_B组合成某种东西:

var store_C;
function C() {
   store_C = process_C(store_A, store_B);
}

假设A()B()C()是公共 API,所有其他东西都是内部代码和实际上是复杂的代码(例如,我不能直接链接两者$.ajax(。

我想使用 jQuery 延迟 API 将上面的代码重构为新的 API,以便我可以请求任何情况:

case1: after(A).do(C)
case1: after(B).do(C)
case2: afterParallelJobsFinished(A, B).do(C)

并确保store_Astore_B按要求更新,并且仅在按要求更新一个或两个 A/B 后store_C更新。


想象我们有网络应用程序,用户可以在其中管理一组收入和支出。

在页面加载时,我们并行从不同的数据源(即$.ajax(获得收入和支出,呈现视图和存储数据(通常混合process_*/store_* =(并显示所有数据到达时total = SUM(incomes) - SUM(expenses)

那是case2.

当用户编辑费用并请求部分页面更新时,我们会case1,因为我们只需要加载/渲染/存储扩展即可获得正确的total = SUM(incomes) - SUM(expenses)

$.when()可以采用任意数量的延迟对象。如果您不知道要拨打多少个电话,它甚至可以使用动态号码。

$.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
    }
  });
}

这是对马修·赫布斯特(Matthew Herbst(的回答的修订,只坚持承诺逻辑。这避免了混合 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;
    });
}

现在,当我熟悉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返回一些明智的东西。但是如果我将公共 API 添加到 callA/callB我可以使用:

$.when(callA(), callB()).done(function(resultA, resultB) {
 // Do stuff here when both calls are done
});