關於JS的EventLoop和線程模型

JS由於操作DOM和用戶交互的用途,是單線程模型的,也就是一次只能執行一個事件,這樣避免混亂的執行機制,比如添加元素的同時又刪除它引起矛盾。而單線程意味着事件和任務需要排隊進行,這就是隊列(queue),隊列是“先進先出”的執行順序,js把一些任務“掛起”,等待前面的任務執行完再回來執行“掛起”任務,所以任務分爲同步任務(synchronous)和異步任務(asynchronous),同步任務指的是在主線程上執行的任務,執行完一個執行下一個,異步任務則是在任務隊列中的某個異步線程。當主線程的堆棧爲空時將任務隊列的event推入堆棧中,處理其它消息前會先處理當前事件回調。

而對於任務隊列,它分爲宏任務(macrotasks)和微任務(microtasks),宏任務包含setTimeout,setInterval,setImmediate,UI rendering等,微任務包括promise(原生),process.nextTick,observe等,整體的script代碼同步執行完就執行microtasks,然後再執行macrotasks,如此反覆循環。

接下來看一段代碼

    var pro=new Promise((res,rej)=>{
		console.log('promise_1');
		res();
	}).then(()=>{
		console.log('promise_2');
	})

	console.log('start')

	const interval = setInterval(() => {  
	  console.log('setInterval')
	}, 0)

	setTimeout(() => {  
	  console.log('setTimeout 1')
	  Promise.resolve()
	      .then(() => {
	        console.log('promise 3')
	      })
	      .then(() => {
	        console.log('promise 4')
	      })
	      .then(() => {
	        setTimeout(() => {
	          console.log('setTimeout 2')
	          Promise.resolve()
	              .then(() => {
	                console.log('promise 5')
	              })
	              .then(() => {
	                console.log('promise 6')
	              })
	              .then(() => {
	                clearInterval(interval)
	              })
	        }, 0)
	      })
	}, 0)

    Promise.resolve()
	    .then(() => {  
	        console.log('promise 1')
	    })
	    .then(() => {
	        console.log('promise 2')
	    })

分析一下,首先執行同步任務,輸出promise_1和start,此時執行任務隊列中第一個任務,輸出promise_2,然後先執行微任務Promise,輸出promise 1和promise 2,然後是任務隊列中的interval定時器,然後是setTimeout定時器,此時interval定時器又進入任務隊列中,又一次輸出setInterval,再執行then裏的定時器,最後清除interval定時器便不再輸出setInterval

所以結果如下:

(純個人理解,如有差錯,一起探討)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章