javascript的执行机制

console.log(1);

console.log(2);

console.log(3);

/*

执行结果:1、2、3

同步任务,按照顺序一步一步执行

*/

``

3.2、同步和异步

console.log(1);

setTimeout(function() {

console.log(2);

},1000)

console.log(3);

/*

执行结果:1、3、2

同步任务,按照顺序一步一步执行

异步任务,放入消息队列中,等待同步任务执行结束,读取消息队列执行

*/

3.3 、异步任务进一步分析

console.log(1);

setTimeout(function() {

console.log(2);

},1000)

setTimeout(function() {

console.log(3);

},0)

console.log(4);

/*

猜测是:1、4、2、3 但实际上是:1、4、3、2

分析:

同步任务,按照顺序一步一步执行

异步任务,当读取到异步任务的时候,将异步任务放置到Event table(事件表格)

中,当满足某种条件或者说指定事情完成了(这里的是时间分别是达到了0ms和1000ms)当指定

事件完成了才从Event table中注册到Event Queue(事件队列),当同步事件完成了,便从

Event Queue中读取事件执行。(因为3的事情先完成了,所以先从Event table中注册到

Event Queue中,所以先执行的是3而不是在前面的2)

*/

3.4、宏任务和微任务

console.log(1);

setTimeout(function() {

console.log(2)

},1000);

new Promise(function(resolve) {

console.log(3);

resolve();

}

).then(function() {

console.log(4)

});

console.log(5);

/*

以同步异步的方式来判断的结果应该是:1、3、5、2、4

但是事实上结果是:1、3、5、4、2

为什么是这样呢?因为以同步异步的方式来解释执行机制是不准确的,更加准确的方式是宏任务和微任务:

因此执行机制便为:执行宏任务 ===> 执行微任务 ===> 执行另一个宏任务 ===> 不断循环

即:在一个事件循环中,执行第一个宏任务,宏任务执行结束,执行当前事件循环中的微任务,

执行完毕之后进入下一个事件循环中,或者说执行下一个宏任务

*/

3.5、是否彻底理解JavaScript执行机制实例

console.log(‘1’);

setTimeout(function() {

console.log(‘2’);

process.nextTick(function() {

console.log(‘3’);

})

new Promise(function(resolve) {

console.log(‘4’);

resolve();

}).then(function() {

console.log(‘5’)

})

})

process.nextTick(function() {

console.log(‘6’);

})

new Promise(function(resolve) {

console.log(‘7’);

resolve();

}).then(function() {

console.log(‘8’)

})

setTimeout(function() {

console.log(‘9’);

process.nextTick(function() {

console.log(‘10’);

})

new Promise(function(resolve) {

console.log(‘11’);

resolve();

}).then(function() {

console.log(‘12’)

})

})

/*

1、 第一轮事件循环流程分析如下:

整体script作为第一个宏任务进入主线程,遇到console.log,输出1。

遇到setTimeout,其回调函数被分发到宏任务Event Queue中。我们暂且记为setTimeout1。

遇到process.nextTick(),其回调函数被分发到微任务Event Queue中。我们记为process1。

遇到Promise,new Promise直接执行,输出7。then被分发到微任务Event Queue中。我们记为then1。

又遇到了setTimeout,其回调函数被分发到宏任务Event Queue中,我们记为s 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 etTimeout2。

宏任务Event Queue 微任务Event Queue

setTimeout1 process1

setTimeout2 then1

上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了1和7。

我们发现了process1和then1两个微任务。

执行process1,输出6。

执行then1,输出8。

好了,第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。

2、 那么第二轮时间循环从setTimeout1宏任务开始:

首先输出2。接下来遇到了process.nextTick(),同样将其分发到微任务Event Queue中,

记为process2。new Promise立即执行输出4,then也分发到微任务Event Queue中,记为then2。

宏任务Event Queue 微任务Event Queue

setTimeout2 process2

then2

第二轮事件循环宏任务结束,我们发现有process2和then2两个微任务可以执行。

输出3。

输出5。

第二轮事件循环结束,第二轮输出2,4,3,5。

3、 第三轮事件循环开始,此时只剩setTimeout2了,执行。

直接输出9。

将process.nextTick()分发到微任务Event Queue中。记为process3。

直接执行new Promise,输出11。

将then分发到微任务Event Queue中,记为then3。

宏任务Event Queue 微任务Event Queue

process3

then3

第三轮事件循环宏任务执行结束,执行两个微任务process3和then3。

输出10。

输出12。

第三轮事件循环结束,第三轮输出9,11,10,12。

整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。

*/

4、相关概念

4.1、JS为什么是单线程的?

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

4.2、JS为什么需要异步?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值