javascript文件异步加载的一个浅坑

694 阅读1分钟
原文链接: jialj.github.io

常用javascript文件异步加载的一种方式如下

a.js中有下面一段代码

var oscript = document.createElement('script');
    oscript.setAttribute('src','b.js');
    oscript.setAttribute('type','text/javascript');
    document.getElementsByTagName('head')[0].appendChild(oscript);

b.js内容如下

//可以是任意一段业务代码
var val,i=1000
for(;i>0;i++){
    val = val*i
}

在a.js中动态加载了b.js。
因为项目中引入了jQuery,此时小李要重构上面这一段代码。改完之后a.js是这样

$("head").append("<script type='text/javascript' src='b.js' ></script>");

简洁明了,把之前4句话完成的内容一句话搞定,write less,do more! 你以为到这里结束了么?


问题来了a.js中的程序修改前后执行逻辑是否一致呢?
此时我们做如下修改
a.js中添加日志

var oscript = document.createElement('script');
    oscript.setAttribute('src','b.js');
    oscript.setAttribute('type','text/javascript');
    document.getElementsByTagName('head')[0].appendChild(oscript);
console.log(3);

b.js中添加日志

console.log(1);
//可以是任意一段业务代码
var val,i=1000
for(;i>0;i++){
    val = val*i
}
console.log(2)

刷新页面,console的输出顺序是 3,1,2。原因很简单,因为,b.js是异步加载的,浏览器在请求b.js资源的时候,a.js会继续执行。b.js请求完成输出了1,2。如果在小李修改后的a.js中加入日志呢?
修改a.js为

$("head").append("<script type='text/javascript' src='b.js' ></script>");
console.log(3);

然后刷新页面此时console的输出顺序成了1,2,3。 whats the f**k。
看了一下jQuery的append方法添加javascript时候的请求:
如图所示
怎么有X-Requested-With:XMLHttpRequest,竟然是ajax请求。肯定是jQuery在搞鬼,翻看query的源码最终发现了原因,当时小张用到的jQuery版本是1.9.1,最终发现在jQuery的domManip方法中,在6178行,有下面一段代码:

if ( node.src ) {
    // Hope ajax is available...
    jQuery.ajax({
        url: node.src,
        type: "GET",
        dataType: "script",
        async: false,
        global: false,
        "throws": true
    });
} else
.......

哈哈,一切大白于天下了!