在导出为CSV之前,如何重构以等待AJAX​​查询完成?

我点击按钮触发下面的代码。 当我运行它时,CSV被创建但是为空。 console.log(rows)输出是预期的,但有一个注释说明Value below was evaluated just now.

如何执行exportToCsv等待AJAX​​调用完成?

 $("#downloadBtn").click(function() { weeks = getWeeks(startDate.val(), endDate.val()); // start downloading the data for (i=0; i< weeks.length; i++) { // contains $.ajax query that appends to "rows" fetchDataWeek( weeks[i][0], weeks[i][1] ); } console.log(rows); exportToCsv( fileName, rows ); }); 

编辑以回应surajck的回答 :

除了使用Promises建议的代码之外,我已经编辑了我的fetchDataWeek函数,如下所示,但是当我运行它时,我得到了Uncaught TypeError: Promise resolver undefined is not a function

 function fetchDataWeek( startDay, endDay ) { startDay = makeDateString(startDay); endDay = makeDateString(endDay); url = "https://api" + startDay + endDay + ".json"; $.ajax({ url: url, success: function(result){ parseHistory(result); _promise.resolve(result); } }); } 

以下是一些通用代码,可帮助您了解:

 $("#downloadBtn").click(function() { weeks = getWeeks(startDate.val(), endDate.val()); // start downloading the data // Create an array to hold all your promises var promiseArray = []; for (i=0; i< weeks.length; i++) { // contains $.ajax query that appends to "rows" var _promise = Q.defer(); // Create a promise (using https://github.com/kriskowal/q) // send this promise to the ajax callback fetchDataWeek( weeks[i][0], weeks[i][1], _promise ); promiseArray.push(_promise) // Push this promise into the array } Promise.all(promiseArray).then( function () { // Wait for all promises to resolve console.log(rows); exportToCsv( fileName, rows ); }) }); 

你的fetchDataWeek代码然后变成:

 function fetchDataWeek( startDay, endDay, _promise ) { startDay = makeDateString(startDay); endDay = makeDateString(endDay); url = "https://api" + startDay + endDay + ".json"; $.ajax({ url: url, success: function(result){ parseHistory(result); _promise.resolve(result); // resolving that promise here }, error: function (error) { _promise.reject(error) // rejecting it in case of error } }); } 

AJAX调用是异步的。 您的代码在加载数据之前执行。 为了防止这种情况,你应该使用一个回调函数,并对那里加载了AJAX的数据进行任何操作。

如果您正在使用JQuery,则承诺看起来像这样(使用基本身份validation来访问端点,这是受保护的):

  var url = "/myEndpoint/"; var req = $.ajax ({ type: "GET", xhrFields: { withCredentials: true }, headers: { 'Authorization': 'Basic ' + btoa(gAccountName + ':' + gAccountPw) }, url: url, dataType: 'json' }); req.done(function(data) { // The data var has your results // process here console.log(data); }); req.fail(function(data) { alert("There was an error loading your list of names. Please try again in a few seconds."); }); }