在导出为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."); }); }