2017-10-04 83 views
0

我正在嘗試編寫一個函數,該函數會給出一個id列表並轉到firebase存儲並檢索每個id的下載URL,然後將URL以相同順序保存在數組中ID數組。在測試中,我發現下載URL以隨機順序返回。下面是上述函數的一些縮小代碼。
1)有沒有辦法讓返回的URL以正確的順序到達?
2)在循環之後使用setTimeout函數等待3秒,否則urlsToDownload數組爲空。是否有更準確的方法等待所有URL被下載?Firebase在循環中調用getDownloadURL以隨機順序返回

function downloadAll() { 
     var storageRef = firebase.storage().ref("/stuffToDownload"); 
     var urlsToDownload = []; 
     var downloadIds = ['1', '2']; 
     for (var x = 0; x < downloadIds.length; x++) { 
      var downloadId = dowloadIds[x]; 
      (function(did) { 
       var storageFileRef = storageRef.child(did); 
       storageFileRef.getDownloadURL().then(function(url) { 
       urlsToDownload.push(url); 
       }).catch(function(error) { 
       console.log("error"); 
       }); 
      })(downloadId); 
      } 
     } 
     } 
     setTimeout(function() { 
     console.log("finished getting file urls", urlsToDownload.length); 
     var index = 0; 
     for(index = 0; index < urlsToDownload.length; index++){ 
      console.log(index + " " + urlsToDownload[index]); 
     } 
     }, 3000); 
    } 
+2

這是因爲'storageFileRef。 getDownloadURL()'是異步的。你的'for'循環一次觸發所有這些請求。您需要等待響應,並在前一個響應到達時才發送下一個請求。另請參見https://stackoverflow.com/questions/4288759/asynchronous-for-cycle-in-javascript –

+1

謝謝,我用你的迴應中的其他職位的參考,併爲我工作 –

+0

很高興聽到:) –

回答

0

你可以做的就是等待要下載的URL,然後檢查urlsToDownload的長度與downloadIds的長度,如果匹配調用一個函數像下面,

storageFileRef.getDownloadURL().then(function(url) { 
      urlsToDownload.push(url); 
      if(urlsToDownload.length==downloadIds.length){ //if you have all the files matching with downloadIds then you will get all the download URL 
      _callConsoleLog() 
      } 
      }) 
var _callConsoleLog=function(){ 
    var index = 0; 
    for(index = 0; index < urlsToDownload.length; index++){ 
     console.log(index + " " + urlsToDownload[index]); 
    } 
} 
+0

這是一個很好的解決方案,使setTimeout被刪除,但據我瞭解,在urlsToDownload的值的順序仍然是隨機的 –

+0

隨機意味着如何?你可以顯示輸出,所以我可以幫你 – MuruGan