这两个英文单字,中文翻译分别是「同步」与「非同步」, 而同步是什么意思呢,今天想作一个让网页中所有的 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);
- }
- }