jQuery ajax调用具有多个依赖关系的链接
我不太了解jQuery的魔术延迟对象。 假设以下代码:
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,而调用依赖于彼此(一个长链):
- 调用
getInitialData
- 调用与
getInitialData
相关的getGreenData
- 调用与
getInitialData
相关的getRedData
- 使用依赖于
getGreenData
和getRedData
getFinalData
调用
正如你所知,2和3可能同时发生。 我想我可以使用jQuery.when()
(或resolve
?),我只是不知道如何在这里应用它。 我想我需要重做函数来始终返回ajax对象?
Pseude-code看起来像这样:
getInitialData().then(getGreenData, getRedData).then(getFinalData)
$ .ajax返回一个jQuery承诺。 then
,您可以调用该承诺将链完成链接到函数。 ajax data
作为promise参数传递给任何最终的回调函数。 这是因为$ .ajax“承诺返回Ajax数据”。
如果您对所有function采用相同的模式,则可以根据需要链接所有function。 通过不调用函数或添加匿名回调,它只是使用每个函数调用产生的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
结合:
例如
// Fetch green data and red data in parallel function GetFinalData () { return $.when(getGreenData(), getRedData()); }
希望这会更好地了解如何将数据从一个调用传递到下一个调用。
首先是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' }); }
现在你的四个“获取…”function,不同之处在于:
- 函数接受
filter
参数 - 函数返回一个承诺
- 回调现在显示为传递给链式
callWebService()
的参数.then()
而不是传递给callWebService()
。 - 回调对返回的数据执行任何必要的操作,并且重要的是,返回它,从而在调用
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; }); }
最后是控制排序和数据流的主程序。
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 });
这是基础知识。 在几乎所有function中,都可以进行各种改进。