在ajax post请求之前加载两个文件

时间:2017-01-31 14:58:16

标签: javascript ajax file asynchronous

我需要为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) { 
      .....
  });

3 个答案:

答案 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.adata.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