简体   繁体   English

具有多个依赖项的jQuery ajax调用链

[英]jQuery ajax call chaining with multiple dependencies

I don't quite understand magic deferred objects with jQuery. 我不太了解jQuery的魔术延迟对象。 Assume the following code: 假设以下代码:

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

The order I want to do things is like so - in the end I will call four webservices whereas the calls depend on each other (one long chain): 我要执行的操作顺序是这样的-最后,我将调用四个Web服务,而调用彼此依赖(一个长链):

  1. Call getInitialData 呼叫getInitialData
  2. Call getGreenData with dependency on getInitialData 依赖于getInitialData调用getGreenData
  3. Call getRedData with dependency on getInitialData 调用依赖于getInitialData getRedData
  4. Call getFinalData with dependencies on getGreenData and getRedData 呼叫getFinalData与依赖getGreenDatagetRedData

As you can tell 2 & 3 could happen simultaneously. 如您所知2和3可能同时发生。 I'm thinking I can use jQuery.when() (or resolve ?), I just don't know how to apply it here. 我想我可以使用jQuery.when() (或resolve吗?),我只是不知道如何在这里应用它。 I think I need to rework the functions to always return the ajax object? 我想我需要重新编写函数以始终返回ajax对象?

Pseude-code would look like this: 伪代码如下所示:

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

$.ajax returns a jQuery promise. $ .ajax返回jQuery承诺。 You can then call then on that promise to chain completion to a function. then ,您可以调用该诺言,将完成链接到一个函数。 The ajax data is passed as the promise parameter to any final callback function. Ajax data作为promise参数传递给任何最终的回调函数。 That is because $.ajax "promises to return the Ajax data". 这是因为$ .ajax“承诺返回Ajax数据”。

If you follow the same pattern for all your functions you can chain everything as you wanted. 如果您对所有功能都遵循相同的模式,则可以根据需要链接所有内容。 By not calling the functions, or adding anonymous callbacks, it simply uses the resulting promises from each function call and combines them together. 通过不调用函数或添加匿名回调,它仅使用每个函数调用产生的承诺并将它们组合在一起。

Something like: 就像是:

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

To run promises in parallel, evaluate the functions immediately and let the resulting promises combine with $.when : 要并行运行promise,请立即评估函数,然后将产生的promise与$.when结合使用:

eg 例如

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

Hopefully this will give a better idea of how to pass data from one call to the next. 希望这会更好地说明如何将数据从一个呼叫传递到下一个呼叫。

First a version of callWebService() that differs in that : 首先是一个不同的callWebService()版本:

  • it doesn't accept a callback 它不接受回调
  • it returns the jqXHR object returned by $.ajax() 它返回由$.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'
    });
}

Now your four "get..." functions, which differ in that : 现在,您有四个“ get ...”函数,不同之处在于:

  • the functions accept a filter parameter 函数接受filter参数
  • the functions return a promise 功能返回承诺
  • the callback now appears as a parameter passed to a chained .then() rather than passing it to callWebService() . 回调现在显示为传递给链的参数.then()而不是将它传递给callWebService()
  • the callback does whatever is necessary with the returned data and, importantly, returns it, thus making the data available further down a promise chain wherever getInitialData() , getGreenData() etc are called. 回调函数对返回的数据执行任何必要的操作,并且重要的是,将其返回,从而使数据在调用getInitialData()getGreenData()等的promise链中进一步可用。
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;
    });
}

Finally the master routine that controls the sequencing and data flow. 最后是控制排序和数据流的主例程。

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() can now be called as follows, with the summary data available in the callback of a chained .then() : 现在,可以按以下方式调用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
});

That's the basics. 这就是基础。 In almost every function, various refinements are possible. 在几乎所有功能中,各种改进都是可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM