我需要为ajax post请求加载两个文件。如何在ajax调用之前确保它们都已加载?当前代码如下所示。
if (options.a) {
var reader = new FileReader();
reader.readAsBinaryString(options.a);
reader.onload = function(evt) {
data.a = window.btoa(evt.target.result);
}
}
if (options.b) {
var reader = new FileReader();
reader.readAsBinaryString(options.b);
reader.onload = function(evt) {
data.b = window.btoa(evt.target.result);
}
}
$.ajax({
url: command,
data: JSON.stringify(data),
type: 'POST',
success: function(result, status) {
.....
});
答案 0 :(得分:1)
正如在@ epascarello的回答中所提到的,承诺将是一种在这里使用的简单方法。
如果你可以使用原生承诺,你可以做这样的事情来摆脱重复的代码和if
- 检查。这也允许在执行$.ajax()
之前加载任意数量的文件。
我们的想法是将promises添加到数组中,然后等待它们全部解析完毕。当文件阅读器完成阅读时,承诺将解决。
var promises = [];
Object.keys(options).map(function(key) {
if (options[key]) {
var promise = new Promise(function(resolve, reject) {
var reader = new FileReader();
reader.readAsBinaryString(options[key]);
reader.onload = function(evt) {
data[key] = window.btoa(evt.target.result);
resolve();
}
});
promises.push(promise);
}
});
//Await all promises in array
Promise.all(promises)
.then(function() {
//All data read, execute ajax
$.ajax({
url: command,
data: JSON.stringify(data),
type: 'POST',
success: function(result, status) {
.....
});
});
答案 1 :(得分:0)
这实际上很棘手。一种可能性是设置计时器以定期检查两个文件的状态(data.a
,data.b
)。而不是直接调用ajax函数,启动计时器。一旦你的计时器功能确定它们都已加载,然后进行你的ajax调用。
if (options.a) {
var reader = new FileReader();
reader.readAsBinaryString(options.a);
reader.onload = function(evt) {
data.a = window.btoa(evt.target.result);
}
}
if (options.b) {
var reader = new FileReader();
reader.readAsBinaryString(options.b);
reader.onload = function(evt) {
data.b = window.btoa(evt.target.result);
}
}
//CHECK THE STATUS OF YOUR FILES EVERY 300 MILLISECONDS
var postHandler = setInterval(postData, 300);
//FUNCTION THAT CHECKS THE STATUS OF FILES, DOES THE AJAX POST, AND CLEARS THE TIMER
function postData() {
if (data.a && data.b) {
clearInterval(postHandler);
$.ajax({
url: command,
data: JSON.stringify(data),
type: 'POST',
success: function(result, status) {
.....
}
});
}
}
答案 2 :(得分:0)
使用promises来处理这种情况。
var d1 = $.Deferred();
var d2 = $.Deferred();
$.when( d1, d2 ).done(function ( value1, value2 ) {
console.log( value1 );
console.log( value2 );
//make your Ajax call
});
d1.resolve( "call one" ); //trigger inside of onload a
d2.resolve( "call two" ); //trigger inside of onload b