JS中另类的同步非阻塞加载

Javascript执行顺序解释

Scripts without async or defer attributes, as well as inline scripts, are fetched and executed immediately, before the browser continues to parse the page.

默认情况下,页面中的JS脚本会阻塞DOM渲染,并且是根据它们出现在文档中的顺序来先后执行的,但是近日发现一种先执行后定义的处理方法:

神策异步载入

(function(para) {

var p = para.sdk_url, n = para.name, w = window, d = document, s = 'script',x = null,y = null;

w['sensorsDataAnalytic201505'] = n;

w[n] = w[n] || function(a) {return function() {(w[n]._q = w[n]._q || []).push([a, arguments]);}};

var ifs = ['track','quick','register','registerPage','registerOnce','clearAllRegister','trackSignup', 'trackAbtest', 'setProfile','setOnceProfile','appendProfile', 'incrementProfile', 'deleteProfile', 'unsetProfile', 'identify','login','logout','trackLink','clearAllRegister'];

for (var i = 0; i < ifs.length; i++) {

w[n][ifs[i]] = w[n].call(null, ifs[i]);

}

if (!w[n]._t) {

x = d.createElement(s), y = d.getElementsByTagName(s)[0];

x.async = 1;

x.src = p;

y.parentNode.insertBefore(x, y);

w[n].para = para;

}

})({

sdk_url: '在 github 下载新版本的 sensorsdata.min.js ',

name: 'sa',

server_url:'数据接收地址'

});

sa.quick('autoTrack'); //神策系统必须是1.4最新版及以上

上面的代码把要执行的函数名和参数存储起来,随后异步加载SDK文件,当SDK文件加载完成后,利用配置的全局变量和其中存储的执行数据,传入真正的方法中执行。

代码解析:

1. 配置参数

sdk_url: 定义了真正可执行代码的远程JS代码地址

name: 当前页面的全局变量,防止变量名冲突,例子中使用了sa

2. 执行过程

sensorsDataAnalytic201505:本地定义的全局变量名和远程JSSDK中变量沟通的桥梁

将name定义为window中的对象,赋值为一个柯里化的函数

ifs声明了远程SDK中可调用的函数名, 通过上面的柯里化函数依次定义了相关函数出来

最后执行SDK异步加载(async)

3. 本地无需等待SDK加载,立即调用需要执行的函数,各函数执行的代码雷同,都是接收可变的参数,将它们拼接作为一个数组[a, arguments],然后append到window[name]._q的property中

sa.function1('param1_1', 'param1_2');

sa.function2('param2_1', 'param2_2');

执行之后,sa._q就会是以下赋值

[

    [function1,'param1_1', 'param1_2']

    [function2,'param2_1', 'param2_2']

]

前提是function1,function2在ifs定义的函数名数组中

你可能感兴趣的:(JS中另类的同步非阻塞加载)