team icon indicating copy to clipboard operation
team copied to clipboard

jquery不同js模块添加domready,domready函数执行报错互相影响分析

Open qiaoqiaowang opened this issue 6 years ago • 0 comments

问题描述

jquery 小于3.0.0的版本,在不同的js模块中添加domready,不同代码块中domready中的代码报错会互相影响。

小知识:不同代码块中的js代码,如果报错,之间互不影响,同一块中,前面代码执行出错,后面代码不被执行。

场景模拟

  • 在jquery版本<3的低版本中。
<script>
    $(function () { //代码块1中添加domready
        console.log('代码块1,第一次打印数据!');// 可以打印
        throw new Error('程序抛出错误!');
        console.log('代码块2,第二次打印数据!');// 无法打印,符合js块执行机制
    });
</script>

<script>
$(function () { //代码块2中添加domready
    console.log('代码块2,第一次打印数据!');// 无法打印
});
</script>

控制台输出: image

  • 在jquery版本>=3的低版本中。
<script>
    $(function () { //代码块1中添加domready
        console.log('代码块1,第一次打印数据!');// 可以打印
        throw new Error('程序抛出错误!');
        console.log('代码块2,第二次打印数据!');// 无法打印,符合js块执行机制
    });
</script>

<script>
    $(function () { //代码块2中添加domready
        console.log('代码块2,第一次打印数据!');// 可以打印
    });
</script>

控制台输出: image

结果分析

  • 在jquery版本<3的低版本中。 当通过$(function(){}) 方法添加domready事件回调时,事件回调方法不会立即被执行,jquery会将其加入到一个队列数组中,页面的domready事件触发之后,会依次遍历该数组队列循环执行(没有加异步处理),这时前面的方法报错后,就会影响后面js代码的执行,符合js的执行机制。

  • 在jquery版本>=3的低版本中。 当通过$(funtion(){}) 方法添加domready事件回调时,每一个domready函数的调用都放在一个setTimeout里面去执行,不同的setTimeout里面的代码执行不会相互影响,所以不会出现后面注册的domready函数不被执行的现象。

场外对比--zepto

对比结果: zepto在 <1.2.0的版本中,且在DOMContentLoaded事件触发之后注册的domready函数之间执行会有影响。 zepto在注册domready事件时,会将事件回调作为形参传给$.fn.ready函数,执行$.fn.ready函数。在$.fn.ready函数中,判断document.readyState,如果DOMContentLoaded事件已经触发,< 1.2.0版本中会立即执行注册的domready事件回调,是非异步的,1.2.0版本中会将该回调放在setTimeout 0 中来执行,是异步的; 否则将注册的domready事件回调添加为DOMContentLoaded原生事件的回调,这样也是异步的。所以只有在1.x且在DOMContentLoaded事件触发之后注册domready函数时,其前后执行是串行非异步的,执行结果报错会有影响。

qiaoqiaowang avatar Dec 11 '17 13:12 qiaoqiaowang