這兩個英文單字,中文翻譯分別是「同步」與「非同步」, 而同步是什麼意思呢,今天想作一個讓網頁中所有的 script 可以動態載入的功能 , 一開始先嘗試使用 document.getElementByTagName('head')[0].appendChild() 寫入 script A,B,C 三個 tag 到 head 中,不過這個方式沒辦法讓 script 依序執行,重覆 reload 後,常常會出現 B > A > C 這種錯誤的執行流程,後來改用 YUI3 Get 功能,發現 YUI3 有個 async options ,只要設定這個值為 false ,就能有正確的 script 執行流程。
以下摘錄 YUI3 async 的說明。
Whether or not to load scripts asynchronously, meaning they're requested in parallel and execution order is not guaranteed. Has no effect on CSS, since CSS is always loaded asynchronously
中文胡亂翻譯應該是「如果你使用非同步方式發送 Request,那所有的 Request 將會以平行方式,同時發送出去,而且無法保證執行的順序」
看完就知道為什麼要加上 async = false 這個功能吧。
blocking , nonblocking
sync & async 在網頁的世界理,是比較像 blocking & nonblocking 的觀念, sync(同步) 每一個 script 會依序載入與執行,後面的 script 會等待前一個 script 載入完成後,才開始執行,所以這是 blocking,一次只能載入一個 script
async(非同步) 則可以一次載入多個 script ,不過沒辦法控制每一個 script 的執行順序,所以這是 nonblocking。
Dynamic load javascript (sync)
瀏覽器(Chrome, Firefox) 預設會將動態載入的 Script Tag 變成非同步處理,也就是 nonblocking ,最後會造成 script 執行的順序錯亂。
為了讓 script 可以按照我們的順序來執行,我們必須在每一個 script tag 加上 async=false。
- scriptTag = document.createElement('script');
- function loadJS(){
- var head = document.getElementsByTagName('head')[0];
- var script = ["scriptA.js", "scriptB.js", "scriptC.js"];
- var stag;
- var i = 0;
- var n = script.length;
- for (i; i<n; i++) {
- scriptTag = document.createElement('script');
- scriptTag.async = false;
- scriptTag.src = script[i];
- if ((i+1) == n) {
- scriptTag.onload = function () {
- console.log("All script is loaded.");
- }
- }
- head.appendChild(scriptTag);
- }
- }
回應 (Leave a comment)