【问题标题】:jQuery ajax call chaining with multiple dependencies具有多个依赖项的 jQuery ajax 调用链
【发布时间】:2015-02-16 06:53:11
【问题描述】:

我不太了解 jQuery 的魔术 deferred 对象。假设如下代码:

function callWebService(uri, filter, callback)
{
  var data = {};

  if (filter && filter != '')
    data['$filter'] = filter;

  jQuery.ajax({
    url: '/_api/lists/' + uri + '/items',
    data: data,
    success: callback,
    dataType: 'json'
  });
}

function getInitialData() {
  callWebService("InitialData", "", function (data) {
    //do stuff with data
  });
}

function getGreenData() {
  callWebService("GreenData", "filter from InitialData", function (data) {
    //do stuff with data
  });
}

function getRedData() {
  callWebService("RedData", "filter from InitialData", function (data) {
    //do stuff with data
  });
}

function getFinalData() {
  callWebService("FinalData", "filter from RedData & GreenData", function (data) {
    //do stuff with data
  });
}

我想做的事情的顺序是这样的——最后我会调用四个 web 服务,而这些调用相互依赖(一个长链):

  1. 致电getInitialData
  2. 调用getGreenData 依赖于getInitialData
  3. 调用getRedData 依赖getInitialData
  4. 调用getFinalData 依赖于getGreenDatagetRedData

如您所知,2 和 3 可能同时发生。我想我可以使用jQuery.when()(或resolve?),我只是不知道如何在这里应用它。我想我需要重新编写函数以始终返回 ajax 对象?

伪代码如下所示:

getInitialData().then(getGreenData, getRedData).then(getFinalData)

【问题讨论】:

  • 不要以大写字母开头函数名,这会使 Stack Overflows 语法高亮中的颜色看起来很奇怪!
  • 如果你 return CallWebService 中的 ajax 方法,你应该可以访问 .then 承诺
  • 固定函数名,直接来自我的 C# 环境;-)
  • 您想要并行调用还是顺序调用,因为这种细微差别会改变我下面的示例?在我的答案中添加了一个平行的例子。对任何错别字表示歉意。 :)
  • Parallel & Sequential ;-) 由于你的回答,我最好的猜测是这样的:getInitialData.when(getGreenData, getRedData).then(getFinalData).done(function()) - 我只需要弄清楚传递给每个承诺的内容,所以我可以在 @ 987654337@电话。

标签: javascript jquery ajax jquery-deferred chaining


【解决方案1】:

$.ajax 返回一个 jQuery 承诺。然后,您可以在该承诺上调用 then 以将完成链接到函数。 ajax data 作为 promise 参数传递给任何最终的回调函数。那是因为 $.ajax “承诺返回 Ajax 数据”。

如果您对所有函数都遵循相同的模式,则可以根据需要链接所有内容。通过不调用函数或添加匿名回调,它只是使用每个函数调用的结果 Promise 并将它们组合在一起。

类似:

function CallWebService (uri, filter)
{
  var data = {};

  if (filter && filter != '')
    data['$filter'] = filter;

  return jQuery.ajax({
    url: '/_api/lists/' + uri + '/items',
    data: data,
    dataType: 'json'
  });
}

function getGreenData() {
  return CallWebService("GreenData", "filter from InitialData");
}

function getRedData() {
  return CallWebService("RedData", "filter from InitialData");
}

function GetInitialData() {
    return CallWebService("InitialData", "").then(GetGreenData);
}

// Fetch green data then red data sequentially
function GetFinalData () {
    return getGreenData().then(getRedData);
}

// Call the final one
GetFinalData().done(function(greendata, reddata){
     Alert("all done!");
});

要并行运行 Promise,请立即评估函数并将生成的 Promise 与 $.when 结合:

例如

// Fetch green data and red data in parallel
function GetFinalData () {
    return $.when(getGreenData(), getRedData());
}

【讨论】:

  • 好答案。我仍然坚持如何将数据从一个呼叫传递到下一个呼叫。我首先要调用 InitialData,然后使用来自 InitialData 的过滤器调用 Green & Red 数据,然后使用来自 Green & Red 的过滤器调用 FinalData。一条长链。
  • @Dennis G:每个承诺都是返回特定数据。任何数据都将作为接收函数的参数传递,每个 promise 一个(按照它们被链接的顺序 - 我相信没有完成,但我真的需要创建一个测试应用程序)。 :)
【解决方案2】:

希望这可以更好地了解如何将数据从一个调用传递到下一个调用。

首先是callWebService() 的一个版本,其不同之处在于:

  • 不接受回调
  • 返回$.ajax()返回的jqXHR对象
function callWebService (uri, filter) {
    var data = {};
    if (filter && filter != '') {
        data.$filter = filter;
    }
    return jQuery.ajax({
        url: '/_api/lists/' + uri + '/items',
        data: data,
        dataType: 'json'
    });
}

现在你的四个“get...”函数,它们的区别在于:

  • 函数接受filter 参数
  • 函数返回一个承诺
  • 回调现在显示为传递给链式.then() 的参数,而不是传递给callWebService()
  • 回调对返回的数据执行任何必要的操作,重要的是,将其返回,从而使数据在 Promise 链的下游可用,无论何时调用 getInitialData()getGreenData() 等。
function getInitialData (filter) {
    return callWebService("InitialData", filter).then(function (data) {
        //do stuff with initial data
        return data;
    });
}
function getGreenData (filter) {
    return callWebService("GreenData", filter).then(function (data) {
        //do stuff with green data
        return data;
    });
}
function getRedData (filter) {
    return callWebService("RedData", filter).then(function (data) {
        //do stuff with red data
        return data;
    });
}
function getFinalData (filter) {
    return callWebService("FinalData", filter).then(function (data) {
        //do stuff with final data
        return data;
    });
}

最后是控制排序和数据流的主例程。

function getAllSortsOfDependentData() {
    return getInitialData().then(function (initialData) {
        var filter1 = initialData...;//some property of initialData (this may be several lines of code)
        var filter2 = initialData...;//some other property of initialData (this may be several lines of code)
        var greenPromise = getGreenData(filter1);
        var redPromise = getRedData(filter2);
        return $.when(greenPromise, redPromise).then(function (greenData, redData) {
            var filter3 = greenData...;//some property of greenData (this may be several lines of code)
            var filter4 = redData...;//some property of redData (this may be several lines of code)
            return getFinalData(filter3, filter4).then(function(finalData) {
                //Now a summary object can be returned.
                //This is possible due to initialData/greenData/redData being accessible from closures formed by outer functions.
                return {
                    initialData: initialData,
                    greenData: greenData,
                    redData: redData,
                    finalData: finalData
                };
            });
        });
    });
}

getAllSortsOfDependentData() 现在可以按如下方式调用,摘要数据在链式.then() 的回调中可用:

getAllSortsOfDependentData().then(function(dataObject) {
    //Everything above is complete.
    //If required, all the fetched data is available here as properties of `dataObject`
    //dataObject.initialData
    //dataObject.greenData
    //dataObject.redData
    //dataObject.finalData
});

这就是基础。几乎在每个功能中,都可以进行各种改进。

【讨论】:

    猜你喜欢
    • 2014-10-16
    • 2018-07-30
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多