2017-01-31 49 views
1

我需要爲ajax發佈請求加載兩個文件。我如何確保它們在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) { 
     ..... 
    }); 
+0

的承諾是什麼,你需要 – epascarello

回答

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

或者你使用的承諾.... – epascarello

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 
1

正如在@ epascarello的答案中已經建議,承諾將是一個簡單的方法在這裏使用。

如果你可以使用本地承諾,你可以做這樣的事情來擺脫重複代碼和if-檢查。這也允許在執行$.ajax()之前加載任意數量的文件。

這個想法是向數組添加promise,然後等到它們全部解決爲止。當文件閱讀器完成閱讀時,承諾將會解決。

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

你可以暗示你不熟悉的問題的概念,調整你的答案或將downvoted。 – Marco

+0

你能更具體嗎? –

+0

您是否測試過您提供的代碼?它適用於你說的乳清?如果是這樣,就像我之前所說的那樣,可能表明你不熟悉或者確定它是有效的。 Answ – Marco