设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 综合聚焦 > 编程要点 > 正文

JavaScript执行机制怎样理解?

发布时间:2022-01-14 14:03 所属栏目:13 来源:互联网
导读:
导读:今天主要给大家分享关于JavaScript执行机制的内容,一些朋友对于这个内容不是很理解,因此下文会分享一下面试题来帮助大家理解JavaScript执行机制,感兴趣的朋友就继续往下看吧。 根据JavaScript的运行环境,锁定它为单线程,任务需要排队执行,如果网站资源
    今天主要给大家分享关于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.开始新的宏任务,反复如此直到所有任务执行完毕
 
    来一盘Promise
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单线程,任务需要排队执行
同步任务进入主线程排队,异步任务进入事件队列排队等待被推入主线程执
行定时器的延迟时间为0并不是立刻执行,只是代表相比于其他定时器更早的被执行
以宏任务和微任务进一步理解js执行机制
整段代码作为宏任务开始执行,执行过程中宏任务和微任务进入相应的队列中
整段代码执行结束,看微任务队列中是否有任务等待执行,如果有则执行所有的微任务,直到微任务队列中的任务执行完毕,如果没有则继续
执行新的宏任务执行新的宏任务,凡是在执行宏任务过程中遇到微任务都将其推入微任务队列中执行
反复如此直到所有任务全部执行完毕.



(编辑:ASP站长网)

    网友评论
    推荐文章
      热点阅读