关于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

所以结果如下:

(纯个人理解,如有差错,一起探讨)

猜你喜欢

转载自blog.csdn.net/weixin_41531446/article/details/85466786