js的运行机制

一、javascript运行机制是很多面试常考的一个问题接下来我们就来一起了解一下js的运行机制吧
js的特点就是单线程,单线程就是在同一时间只能做同一件事,而且必须一件事情做完之后才能做另一件事情
二、js的消息队列
单线程就意味着所有的事情要排队一个一个进行
所以js设计就分成了两任务,一种是同步任务,另一种是异步任务

同步任务:在主线程上依次排队执行
异步任务:不进入主线程,而进入 任务队列 的任务,只有任务队列通知主线程那个异步的任务可以执行了,异步任务才能执行

三、js中的异步操作
setTimeout
setInterval
ajax
promise
I/O
注意:new Promise 是会进入到主线程中立即执行 而promise.then则属于微任务
四、宏任务和微任务
宏任务: script setTimeout setInterval
微任务:promise.then promise.nextTick(node)
五、事件循环 Event Loop
1)整体的script标签作为第一个宏任务开始执行的时候,会把script标签内的代码分为两部分 一是同步任务 二是异步任务
2)同步任务直接进入主线程依次执行
3)异步任务会再分为宏任务和微任务
4)宏任务会进入Evnet Table 中,并在里面注册回调函数,每当指定的事件完成时,Event Table 会将这个函数移到Event Queue中
微任务也会进入一个Event Table中,并在里面注册回调函数,每当指定的事件完成时Event Table 会将这个函数移到Event Queue中
5)主线程内的任务执行完毕之后,会检查微任务的Event Queue 如果有微任务就会全部执行。如果 没有就是执行下一个宏任务
上述过程 不断重复 就是事件循环 Event Loop
代码走起
1)

console.log(1)

setTimeout(function() {
    console.log(2)
}, 0)

console.log(3)

//执行结果 1  3  2

分析
//执行结果 1 3 2
//1、console.log(1) 是同步任务 直接打印1
//2、setTimeout是异步任务,且是宏函数,放到宏函数队列中,等待下次事件循环才会执行
//3、console.log(3)是同步任务,直接打印3
//4、主线程执行完毕, 没有微任务,第一轮循环结束,开始第二轮 在将宏任务setTimeout 放到主线程开始执行

2)

	setTimeout(function() {
	        console.log(1)
	    })

    new Promise(function(resolve) {
        console.log(2)
        resolve()
    }).then(function() {
        console.log(3)
    })
    console.log(4)
        // 结果 2 4 3 1

分析:
// 结果 2 4 3 1
// 分析
// 1、setTimeout是异步 宏函数,放到宏函数队列里去
// 2、new Prommise 是同步函数 直接执行 输出2
// 3、promise.then是微任务,放到微任务队列中
// 4、console.log(4)是同步任务 直接执行 打印4
// 5、此时主线程任务已经自行完毕 ,开始执行微任务队列
// 微任务队列里有 promise.then 执行打印 3
// 6、微任务执行完毕第一轮循环结束,开始第二轮,从宏任务列表取出第一个宏任务
// 到主线程上指向,因此setTimeout执行打印1
3)

 		console.log(1)
        setTimeout(function() {
            console.log(2)
        }, 0)
        Promise.resolve().then(function() {
            console.log(3)
        }).then(function() {
            console.log('我是微任务里的微任务')
        })
        console.log(5)
    // 结果  1 5  3 我是微任务里的微任务 2
    // 1、console.log(1) 同步任务 直接打印1
    ///2、setTimeout 异步,宏函数 放到宏任务队列里
    ///3、Promise.resolve().then()是微任务 放到微任务队列里
    // 4、console.log(5) 是同步任务直接执行 打印5
    // 5、此时主线程上的任务已经执行完毕,检查微任务队列 有Promise.resolve.then() 
    // 执行并打印 3 微任务执行的时候发现新的微任务 直接执行并打印 '我是微任务里面的微任务'
    // 6、微任务队列执行完毕 本轮循环结束,开开始下一轮,宏任务先执行 ,setTimemout到主线程执行打印2
  1.  function a(x, y) {
         console.log(1)
         setTimeout(function() { //t1
             console.log(2)
         }, 1000)
     }
     a();
     setTimeout(function() { //t2
         console.log(3)
     })
    
     new Promise(function(resolve) {
         console.log(4)
         setTimeout(function() { //t3
             console.log(5)
         }, 100)
         for (var i = 0; i < 100; i++) {
             i == 99 && resolve()
         }
     }).then(function() {
         setTimeout(function() { //t4
             console.log(6)
         }, 0)
         console.log(7)
     })
     console.log(8)
         // 结果1 4 8 7 3 6 5 2
         // 1、a() 是同步任务 直接打印1 
         // 2、a()里面的setTimeout 是异步宏函数 放到宏函数队列    t1
         // 3、a()下面的setTimeout是异步宏函数 放到宏函数队列     t2
         // 4、new Promise里是同步函数直接打印4
         // 5、Promise下面的setTimeout是异步宏函数 放到宏函数队列 t3
         // 6、promise 里面的for循环水hi同步任务 直接执行
         // 7、promise.then 是微任务,放到微任务队列
         // 8、console.log(8) 是同步任务,直接打印8
         // 9、此时主线程任务执行完毕,检查微任务队列中有 Promise.then 执行微任务
         // 发现有setimeout是异步宏函数 放到宏函数队列            t4
         // console.log(7)是同步任务,直接执行 打印7
         // 10、微任务执行完毕,第一轮循环结束 开始下一轮
         // 11、开始新的一轮 ,检查宏任务列表有 t1 ,t2,t3 ,t4 ,按延迟时间执行
         // 依次执行 t2 -> t4 -> t3 -> t1    3,6,5,2
    

5)

 setTimeout(function() { //t1
    console.log(1)
    setTimeout(function() { //t2
        console.log(2)
    })
}, 0)
setTimeout(function() { //t3
        console.log(3)
    }, 0)
    // 结果  1 3 2
    // 分析
    // t1 setTimeout是异步宏函数 放到宏函数队列
    // 第三个放到t3 setTimeout是异步宏函数 放到宏函数队列
    // 没有微任务 第一次循环结束
    // 取出 t1 console.log(1) 同步任务,打印1
    // t1 里有 t2 setTimeout 异步宏函数,放在宏函数队列
    // 没有微任务 第二次循环结束
    // 取出 t3 执行 打印 3
    // 没有微任务,第三次循环结束 
    // 取出t2 直接打印2
    // 没有微任务,也没有宏任务 第四次循环结束
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值