JavaScript执行机制如何理解?
Admin 2021-09-17 群英技术资讯 447 次浏览
今天主要给大家分享关于JavaScript执行机制的内容,一些朋友对于这个内容不是很理解,因此下文会分享一下面试题来帮助大家理解JavaScript执行机制,感兴趣的朋友就继续往下看吧。
根据JavaScript的运行环境,锁定它为单线程,任务需要排队执行,如果网站资源比较大,这样会导致浏览器加载会很慢,但实际上并没有,大家肯定立刻想到了同步和异步。
所谓的同步和异步也是在排队,只是排队的地方不同。
同步任务进入主线程排队,异步任务进入事件队列中排队
同步任务和异步任务进入到不同的队列中,也就是上面讲的在不同地方排队。
同步任务进入主线程,异步任务进入事件队列,主线程任务执行完毕,事件队列中有等待执行的任务进入主线程执行,直到事件队列中任务全部执行完毕。
console.log('a') setTimeout(function(){ console.log('b') }, 200) setTimeout(function(){ console.log('c') }, 0) console.log('d')
a d c b
从上到下,该进入主线程的进入主线程,该进入事件队列的进入事件队列。
那么主线程中存在console.log('a')和console.log('d'),定时器setTimeout延迟一段时间执行,顾名思义异步任务进入事件队列中,等待主线程任务执行完毕,再进入主线程执行。
定时器的延迟时间为0并不是立刻执行,只是代表相比于其他定时器更早的进入主线程中执行。
for(var i = 0; i < 10; i++) { setTimeout(function() { console.log(i) }, 1000) }
结果:十个10
每次for循环遇到setTimeout将其放入事件队列中等待执行,直到全部循环结束,i作为全局变量当循环结束后i = 10,再来执行setTimeout时i的值已经为10, 结果为十个10。
将var改为let,变量作用域不同,let作用在当前循环中,所以进入事件队列的定时器每次的i不同,最后打印结果会是 0 1 2...9。
除了经常说的同步任务和异步任务之外,更可分为宏任务,微任务
主要宏任务:整段脚本scriptsetTimeoutsetTimeout...
主要微任务:promise.then...
执行流程:
1.整段脚本script作为宏任务开始执行
2.遇到微任务将其推入微任务队列,宏任务推入宏任务队列
3.宏任务执行完毕,检查有没有可执行的微任务
4.发现有可执行的微任务,将所有微任务执行完毕
5.开始新的宏任务,反复如此直到所有任务执行完毕
const p = new Promise(resolve => { console.log('a') resolve() console.log('b') }) p.then(() => { console.log('c') }) console.log('d')
结果:a b d c
1.整段script进入宏任务队列开始执行
2.promise创建立即执行,打印ab
3.遇到promise.then进入微任务队列
4.遇到console.log('d')打印d
5.整段代码作为宏任务执行完毕,有可执行的微任务,开始执行微任务,打印c。
setTimeout(function(){ console.log('setTimeout') }, 0) const p = new Promise(resolve => { console.log('a') resolve() console.log('b') }) p.then(() => { console.log('c') }) console.log('d')
结果:a b d c setTimeout
1.setTimeout进入宏任务队列
2.promise创建立即执行,打印ab
3.遇到promise.then进入微任务队列
4.遇到console.log('d')打印d
5.有可执行的微任务,打印c
6.微任务执行完毕,开始执行新的宏任务,setTimeout开始执行,打印setTimeout
setTimeout(function(){ console.log('setTimeout') }, 0) const p = new Promise(resolve => { console.log('a') resolve() console.log('b') }) p.then(() => { console.log('c') setTimeout(function(){ console.log('then中的setTimeout') }, 0) }) console.log('d')
结果:a b d c setTimeout then中的setTimeout
1.同上
2.执行微任务打印c,遇到setTimeout将其推入宏任务队列中
3.定时器延迟时间相同,开始按照顺序执行宏任务,分别打印setTimeoutthen中的setTimeout
console.log('a'); new Promise(resolve => { console.log('b') resolve() }).then(() => { console.log('c') setTimeout(() => { console.log('d') }, 0) }) setTimeout(() => { console.log('e') new Promise(resolve => { console.log('f') resolve() }).then(() => { console.log('g') }) }, 100) setTimeout(() => { console.log('h') new Promise(resolve => { resolve() }).then(() => { console.log('i') }) console.log('j') }, 0)
结果:a b c h j i d e f g
1.打印a
2.promise立即执行,打印b
3.promise.then推入微任务队列
4.setTimeout推入宏任务队列
5.整段代码执行完毕,开始执行微任务,打印c,遇到setTimeout推入宏任务队列排队等待执行
6.没有可执行的微任务开始执行宏任务,定时器按照延迟时间排队执行
7.打印h j,promise.then推入微任务队列有
8.可执行的微任务,打印i,继续执行宏任务,打印d
9.执行延迟为100的宏任务,打印e f,执行微任务打印g,所有任务执行完毕
console.log('start') a().then(() => { console.log('a_then') }) console.log('end') function a() { console.log('a_function') return b().then((res) => { console.log('res', res) console.log('b_then') return Promise.resolve('a方法的返回值') }) } function b() { console.log('b_function') return Promise.resolve('返回值') }
结果:start a_function b_function end res 返回值 b_then a_then
根据上面例子的流程讲解来思考这个,加深理解
关于javascript执行机制相比现在有更清楚的认识了吧,上面提到的面试问题对大家理解javascript执行机制还是有一定的帮助的,大家可以参考一下,想要了解更多javascript执行机制的内容,大家可以关注群英网络其它相关文章。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
Javascript修改元素属性怎样做?想要修改元素属性,我们可以使用元素对象.attribute = new value和setAttribute()函数这两种方法,具体怎样使用呢?文中的示例代码介绍得很详细,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。
这篇文章主要为大家介绍了Vue.js中动态更改svg的相关属性详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
这篇文章主要为大家详细介绍了vue+element ui实现锚点定位,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
相信很多朋友有看到过代码雨这样的效果,觉得挺炫酷的,但是又不知道怎么样做,其实要实现炫酷的代码雨效果并不困难,我们用JS+canvas就可以轻松搞定,下面是实现效果和代码,感兴趣的就继续往下看吧。
在实际应用中,我们有时候会遇到“JS中正则匹配使用有哪些坑要注意”这样的问题,我们该怎样来处理呢?下文给大家介绍了解决方法,希望这篇“JS中正则匹配使用有哪些坑要注意”文章能帮助大家解决问题。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008