1. 程式人生 > >關於JS的EventLoop和執行緒模型

關於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

所以結果如下:

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