2015-08-29 60 views
3

我正在構建一個使用一些外部js文件的網站。我通過下面的代碼加載文件,但如果一個或多個文件下載失敗,我不知道如何繼續。我應該不斷請求他們,直到他們全部下載?爲每個文件做一個單獨的onload事件會更好嗎?我怎麼知道哪個文件加載失敗,需要重新請求?通過Promises異步加載外部js文件的最佳方法

var filesToLoad = ["https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"]; 

var loader = new ScriptLoader(); 
filesToLoad.forEach(function(file) { 
    loader.add(file); 
}); 

loader.loaded(function(failedCallbackF) { 
    console.log("Error."); 
    //Try getting the files again?? 
}); 

function ScriptLoader() { 
    var promises = []; 

    this.add = function(url) { 
     var promise = new Promise(function(resolve, reject) { 

      var script = document.createElement('script'); 
      script.src = url; 

      script.addEventListener('load', function() { 
       resolve(script); 
      }, false); 

      script.addEventListener('error', function() { 
       reject(script); 
       console.log('was rej'); 
      }, false); 

      document.body.appendChild(script); 
     }); 

     promises.push(promise); 
    }; 

    this.loaded = function(callbackOnFailed) { 
     Promise.all(promises).then(function(result1) { 
      console.log('Script loaded from:', result1); 
     }, callbackOnFailed); 
    }; 
} 
+0

爲您的應用程序工作是否需要這些腳本?如果是這樣的話,你還有什麼其他選擇? –

+0

我認爲你必須爲每個文件創建新的實例。這將是一個好處,如果任何文件將無法加載,然後在其錯誤的功能,你可以重新加載它只。 – Eshu

+0

@Joanquin O我應該重構我的代碼,讓它每次都有「拒絕(腳本)」命令時,就會產生一個新的承諾,並且會像這樣循環,直到所有承諾都解決爲止。 – Autumn

回答

3

可能這會幫助你。

var filesToLoad = ["https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"]; 

filesToLoad.forEach(function(file) { 
    var loader = new ScriptLoader(); 
    loader.add(file) 
    loader.loaded(function(failedCallbackF) { 
     console.log("Error."); 
     //reload this file 
    }); 

}); 

function ScriptLoader() { 
    var promises = []; 

    this.add = function(url) { 
     var promise = new Promise(function(resolve, reject) { 

      var script = document.createElement('script'); 
      script.src = url; 

      script.addEventListener('load', function() { 
       resolve(script); 
      }, false); 

      script.addEventListener('error', function() { 
       reject(script); 
       console.log('was rej'); 
      }, false); 

      document.body.appendChild(script); 
     }); 

     promises.push(promise); 
    }; 

    this.loaded = function(callbackOnFailed) { 
     Promise.all(promises).then(function(result1) { 
      console.log('Script loaded from:', result1); 
     }, callbackOnFailed); 
    }; 
} 
4

那麼,有一個官方的API爲它叫做「動態加載器API」,我推薦你使用它,或者它勻(喜歡的東西SystemJS)。

System.import("yourScriptFile.js").then(function(){ 
    // script loaded. 
}); 

如果要加載多個文件,你還可以用它:

Promise.all(["url1", "url2"].map(System.import)).then(function(){ 
    // loaded all here 
}); 
+0

對於加載多個文件,我怎麼知道哪個文件加載失敗,需要再次請求? – Autumn

+0

@Autumn腳本文件爲什麼會加載失敗?無論如何,這不是你在常規腳本標記中所做的事情。如果你真的想要你可以在返回的promise上使用'.catch'並在那裏重試。 –

相關問題