JavaScript 运行机制:Event Loop

JavaScript 是单线程语言。单线程就意味着需要排队,前一个任务完成才能执行下一个任务。所以任务分为两种,同步任务和异步任务。

  • 同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行下一个任务。
  • 异步任务指的是不进入主线程,而进入“任务队列”的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

不同的任务源会被分配到不同的 Task 队列中,任务源可以分为 微任务(microtask)和 宏任务(macrotask)。

  • 宏任务:包括整体代码script,setTimeout,setInterval
  • 微任务:Promise.then(非new Promise),process.nextTick(node中)

异步执行的运行机制如下:(同步执行可以视为没有异步任务的异步执行)

  1. 所有同步任务都在主线程上执行,这属于宏任务,形成一个执行栈。先执行宏任务在执行微任务
  2. 主线程之外,还存在一个任务队列。异步任务只要有了运行结果,就在任务队列中放置一个事件。
  3. 执行栈中的所有同步任务执行完毕,系统就会读取任务队列,将对应的异步任务放入执行栈,开始执行微任务
  4. 主线程不断重复上面的第三步。

主线程丛任务队列中读取事件,这个过程是循环不断的,所以这种运行机制又称为 Event Loop(事件循环)

除了放置异步任务的事件,任务队列还可以放置定时事件。定时器功能主要由setTimeout()和setInterval()这两个函数来完成,它们的内部运行机制完全一样,区别在于前者指定的代码是一次性执行,后者则为反复执行。

	console.log('1');
	setTimeout(function() {
	    console.log('2');
	    process.nextTick(function() {
	        console.log('3');
	    })
	    new Promise(function(resolve) {
	        console.log('4');
	        resolve();
	    }).then(function() {
	        console.log('5')
	    })
	})
	输出:
	1
	2
	4
	3
	5


	1. 宏任务同步代码console.log('1'),不多说
	2. setTimeout,加入宏任务Event Queue,没有发现微任务,第一轮事件循环走完
	3. 第二轮事件循环开始,先执行宏任务,从宏任务Event Queue中独取出setTimeout的回调函数
	4. 同步代码console.log('2'),发现process.nextTick,加入微任务Event Queue
	5. new Promise,同步执行console.log('4'),发现then,加入微任务Event Queue
	6. 宏任务执行完毕,接下来执行微任务,先执行process.nextTick,然后执行Promise.then
	7. 微任务执行完毕,第二轮事件循环走完,没有发现宏任务,事件循环结束

猜你喜欢

转载自blog.csdn.net/weixin_42186513/article/details/83348478