【问题标题】:load two files before ajax post request在ajax post请求之前加载两个文件
【发布时间】:2017-01-31 14:58:15
【问题描述】:

我需要为 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);                   
    }                                                                                                                                         
  }                
  $.ajax({                                                                     
    url: command,                                                              
    data: JSON.stringify(data),                                                
    type: 'POST',                                                              
    success: function(result, status) { 
      .....
  });

【问题讨论】:

  • 承诺就是你所需要的

标签: javascript ajax file asynchronous


【解决方案1】:

正如@epascarello 的回答中已经建议的那样,promise 将是一种在这里使用的简单方法。

如果您可以使用本机承诺,您可以执行类似的操作来消除重复代码和if-checks。这也允许在执行 $.ajax() 之前加载任意数量的文件。

这个想法是向数组添加承诺,然后等到它们全部解决。当文件阅读器完成读取时,承诺将得到解决。

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) {
            .....
          });
      });

【讨论】:

  • 您可以建议您不熟悉问题的概念,调整您的答案或将被否决。
  • 你能说得更具体点吗?
  • 你测试过你提供的代码吗?它的工作原理你说的乳清?如果是这样,就像我之前说的那样,可能表明您不熟悉或确定它有效。回答
  • could这个词是can这个词的变形,用来表达可能性或过去的能力,以及使建议和要求。我不会编辑我的答案,因为它是完全有效的。建议将其作为编辑。
【解决方案2】:

使用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

【讨论】:

    【解决方案3】:

    这实际上很难做到。一种可能性是设置一个计时器来定期检查两个文件的状态(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) { 
            .....
          }
        });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-31
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 2012-11-11
      相关资源
      最近更新 更多