Javascript 在导出到CSV之前,如何重构以等待AJAX查询完成?
我有下面的代码触发按钮点击。当我运行它时,CSV已创建,但为空。Javascript 在导出到CSV之前,如何重构以等待AJAX查询完成?,javascript,jquery,ajax,Javascript,Jquery,Ajax,我有下面的代码触发按钮点击。当我运行它时,CSV已创建,但为空。console.log(rows)输出与预期一致,但有一条注释说下面的值刚刚计算过。 如何使exportToCsv的执行等待AJAX调用完成 $("#downloadBtn").click(function() { weeks = getWeeks(startDate.val(), endDate.val()); // start downloading the data for (i=0; i< we
console.log(rows)
输出与预期一致,但有一条注释说下面的值刚刚计算过。
如何使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 );
});
AJAX调用是异步的。代码在加载数据之前执行。为了防止这种情况发生,您应该使用回调函数,并在其他地方对使用AJAX加载的数据执行任何操作。以下是一些通用代码,以帮助您理解:
$("#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 );
})
});
如果您使用的是JQuery,承诺如下(使用基本身份验证访问端点,这是安全的):
在回调中执行
exportToCsv
。您的意思是在for
循环中触发ajax查询?在这种情况下,您需要创建一个承诺的数组,每个承诺对应一个ajax
。然后,当所有这些文件都已完成时,执行exportToCsv
resolved@surajck,那会是什么样子?这是jQuery的第1天me@surajck,或者有比for循环更好的方法来构造它吗?在其最简单的形式中,您可以在异步请求的回调函数中增加一个计数器,如果该计数器已达到请求数,则调用导出函数。但您可能也希望对错误做出反应,否则,如果其中一个请求因任何原因失败,您的导出可能永远不会启动。Promissions将是一种更高级的方法。我理解这一点,但我不确定如何进行重构,以便在exportToCsv
之前完成所有AJAX调用。您究竟在用AJAX查询什么?它是一个PHP脚本吗?如果是,我会将循环移动到PHP并在那里输出所需的数组,因此您只需要一个AJAX调用,就可以在回调函数中执行您想要的任何操作。不,这是一个我无法控制的外部API,一次只能访问一周。在这种情况下,surajck提出了一个优秀的解决方案,请使用它。这不是确切的代码,Promise
语句的语法会因您使用的库而有所不同。现在查看一下。谢谢我确信这是正确的方法,但我犯了一个错误。我已经编辑了这个问题来添加细节。我建议你使用promise库。试试这个:@JamieBull,我已经编辑了我的答案以适应更新后的问题
$("#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 );
})
});
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
}
});
}
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.");
});
}