第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定

JavaScipt 中的事件循環(huán)(event loop),以及微任務(wù) 和宏任務(wù)的概念

標(biāo)簽:
JavaScript

说事件循环(event loop)之前先要搞清楚几个问题。

1. js为什么是单线程的?

  试想一下,如果js不是单线程的,同时有两个方法作用dom,一个删除,一个修改,那么这时候浏览器该听谁的?

 

2.js为什么需要异步?

  如果js不是异步的话,由于js代码本身是自上而下执行的,那么如果上一行代码需要执行很久,下面的代码就会被阻塞,对用户来说,就是”卡死”,这样的话,会造成很差的用户体验。

 

3.js是如何实现异步的?

  既然js是单线程的,那么js是如何实现异步的呢,是通过事件循环(event loop),理解了event loop 就理解了js的执行机制。

 

4.浏览器中的多线程?

  js是单线程的,但是浏览器是多线程的,多个线程相互配合以保持同步,浏览器下的常驻线程有

  • js线程

  • GUI渲染线程,(它与javaScript线程是互斥的)

  • 事件线程(,onchange,…)

  • 定时器线程(setTimeout, setInterval)

  • 异步http线程(ajax)

 

5. javaScript 的事件循环(event loop)

既然js是单线程的,那么所有的任务就需要排队执行。



  • javaScript 中的任务可以被划分为宏任务(Macrotask)或者微任务(Microtask)


  • 像鼠标事件,键盘事件,"ajax","setTimeout"等就属于宏任务,需要注意的是,主线程的整体代码(script标签),也是一个宏任务


  • process.nextTick,PromiseA.then(), MutaionObserver 就属于微任务




简单概括一下事件循环,就是



1.执行宏任务队列中第一个任务,执行完后移除它


2.执行所有的微任务,执行完后移除它们


3.执行下一轮宏任务(重复步骤2)


如此循环就形成了event loop,其中,每轮执行一个宏任务和所有的微任务


 


下图很形象的描述了event loop









网上有用异步任务和同步任务来说明这个问题的,但是我觉得用宏任务和微任务更好点。

 

下面我通过分析一个示例来说一下:


复制代码


console.log(1);

setTimeout(function(){
    console.log(2)
},10);new Promise(function(resolve){
    console.log(3)    for( var i=100000 ; i>0 ; i-- ){
        i==1 && resolve()
    }
    console.log(4)
}).then(function(){
    console.log(5)
}).then(function(){ 
console.log(6) 
})console.log(7);


复制代码


打印出来的结果是:1 3 4 7 5 6 2


我们分析一下整个过程


1. 首先执行主线程这个宏任务,从上到下执行,遇到console.log(1); 打印1出来


2. 遇到setTimeout,把它丢给定时器线程处理,然后继续往下执行,并不会阻塞10毫秒,而此处定时器线程会在,主线程执行完后的10毫秒,把回调函数放入宏任务队列。


3. 遇到new Promise,直接执行,先打印 ‘3‘ 出来,然后执行for循环,达到条件之后,把promise的状态改为resolved,继续执行打印 ‘4’ 出来


4.遇到promise的then, 属于微任务,则把回调函数放入微任务队列


5.又遇到promise的then, 属于微任务,则把回调函数放入微任务队列


6. 遇到console.log(7) 打印 ‘7’ 出来


7. 宏任务执行完后会执行所有待执行的微任务,所以会相继打印 ‘6’, ‘7’ 出来。


至此第一轮循环已经结束了,第一轮循环里的宏任务和微任务都会被移除出任务队列,接下来开启第二轮循环,


1.首先查找是否有宏任务,由于setTimeout 的回调被放入了宏任务队列,这里会执行回调函数的代码,打印了 ‘2’ 出来


2. 接着查找是否有微任务,发现没有微任务,则本轮循环结束


接下来会重复上面的步骤,这就是event loop 了。后续当我们触发点击事件,有回调函数的话,回调函数也会被放入宏任务队列,一旦队列里重新有了任务,就会被执行。


 


6. 扩展题目


如果能把上面这道题的流程说清楚,那么恭喜你,对event loop理解的不错了。 下面我们再利用上面的题目扩展一下,加深理解。


下面的代码打印出来的结果是什么?


复制代码


console.log(1);

setTimeout(function(){    new Promise(function(resolve){
    console.log('promise in setTimeout1');
    resolve();
    }).then(function(){
        console.log('then in setTimeout1');
    })
},10);new Promise(function(resolve){
    console.log(3);    for( var i=100000 ; i>0 ; i-- ){
        i==1 && resolve();
    }
    console.log(4)
}).then(function(){
    console.log(5);
});

setTimeout(function(){
    console.log('setTimeout2');
},10);

console.log(7);


复制代码




结果如下:



可以发现,第二个setTimeout 的回调函数,执行的比第一个setTimeout里面的promise.then()的回调要晚,这是因为每次循环只执行一个宏任务,但是却会执行所有待执行的微任务,而第二个setTimeout在宏任务队列的位置在第一个setTimeout后面。


 


这个就是我理解的JavaScipt 事件循环机制,参考了很多文章,也自己做了很多思考写出来的,码字不易,觉得有帮助可以点个赞哦。也欢迎留言交流


参考文章


https://segmentfault.com/a/1190000012806637?utm_source=tag-newest


http://www.ruanyifeng.com/blog/2014/10/event-loop.html


https://zhuanlan.zhihu.com/p/33127885


https://zhuanlan.zhihu.com/p/33136054


https://stackoverflow.com/questions/25915634/difference-between-microtask-and-macrotask-within-an-event-loop-context

原文出处:https://www.cnblogs.com/daisygogogo/p/10116694.html  

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評論
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊有機(jī)會得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報(bào)

0/150
提交
取消