jQuery ajax调用具有多个依赖关系的链接

时间:2014-12-17 16:38:13

标签: javascript jquery ajax jquery-deferred chaining

我不太了解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
  });
}

我想要做的事情是这样的 - 最后我将调用四个webservices,而调用依赖于彼此(一个长链):

  1. 致电getInitialData
  2. 依赖getGreenData
  3. 致电getInitialData
  4. 依赖getRedData
  5. 致电getInitialData
  6. 使用getFinalDatagetGreenData
  7. 依赖于getRedData

    你可以告诉2& 3可以同时发生。我想我可以使用jQuery.when()(或resolve?),我只是不知道如何在这里应用它。我想我需要重做函数来总是返回ajax对象吗?

    Pseude-code看起来像这样:

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

2 个答案:

答案 0 :(得分:4)

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

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

类似的东西:

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!");
});

要并行运行promises,请立即评估函数,并将结果承诺与$.when结合使用:

e.g。

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

答案 1 :(得分:0)

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

首先是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'
    });
}

现在你的四个“获取......”功能,其不同之处在于:

  • 这些函数接受filter参数
  • 函数返回一个承诺
  • 回调现在显示为传递给已链接.then()的参数,而不是将其传递给callWebService()
  • 回调对返回的数据执行任何必要的操作,并且重要的是,返回它,从而在调用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
});

这是基础知识。在几乎所有功能中,都可以进行各种改进。