由浅入深解释JS执行机制 EventLoop

一、微任务与宏任务

JS中的任务可分为以下两类

·macro-task(宏任务):包括整体代码script,setTimeout,setInterval
·micro-task(微任务):Promise.then,process.nextTick

JS执行过程优先执行所有宏任务,之后执行微任务,之后继续新的宏任务,之后又是微任务一直循环执行。

	console.log('start');
	new Promise(function(resolve) {
		console.log('promise');
		resolve();
	}).then(function() {
		console.log('then');
	})
	console.log('end');

依次输出start->promise->end->then
遇见第一个console属于宏任务直接输出,遇见promise属于宏任务直接输出,遇见then输入微任务放入微任务队列中,遇见最后的console属于宏任务直接输出,最后执行微任务队列中的then。

	console.log('start');
	new Promise(function(resolve) {
		console.log('promise1');
		resolve();
	}).then(function() {
		new Promise(function(resolve) {
			console.log('promise2');
			resolve();
		}).then(function() {
			console.log('then');
		})
	})
	console.log('end');

如果理解的话你可以尝试思考下上面代码会的输出顺序

start->promise1->end->promise2->then

二、异步

现在我们说JS处理异步的方式:
·同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
·当指定的事情完成时,Event Table会将这个函数移入Event Queue。
·主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
·上述过程会不断重复。

	console.log('start');
	setTimeout(() => {
		console.log('setTimeout');
	}, 0);
	console.log('end');

依次输出:start->end->setTimeout
遇见第一个console属于同步任务直接执行,遇见第二个setTimeout属于异步任务,进入Event Table并注册函数,0秒后推入Event Queue。遇见下一个console直接输出,同步任务执行完后。主进程执行Event Queue中的回调函数输出setTimeout

三、异步+微任务

知道了异步的执行方式,那异步与微任务同时出现的情况也可以分析。

	console.log('start');
	new Promise(function(resolve) {
		setTimeout(() => {
			console.log('setTimeout1');
		}, 0);
		resolve();
	}).then(function() {
		console.log('then');
		setTimeout(() => {
			console.log('setTimeout2');
		}, 0);
	})
	setTimeout(() => {
		console.log('setTimeout3');
	}, 0);
	console.log('end');

依次输出:start->end->then->setTimeout1->setTimeout3->setTimeout2
遇见console.log(‘start’)属于宏任务/同步任务直接执行,遇见Promise中的setTimeout属于宏任务/异步任务,进入Event Table并注册函数,0秒后推入Event Queue,遇见then,属于微任务推入微任务队列中,遇见最后一个setTimeout属于宏任务/异步任务,进入Event Table并注册函数,0秒后推入Event Queue,遇见console.log(‘end’)属于宏任务/同步任务之间执行,然后执行微任务中的then函数中的console.log(‘then’);属于宏任务/同步任务直接执行,然后setTimeout,进入Event Table并注册函数,0秒后推入Event Queue,然后依次执行进入Event Queue的三个console。

	console.log('start');
	new Promise(function(resolve) {
		setTimeout(() => {
			console.log('setTimeout1');
		}, 0);
		resolve();
	}).then(function() {
		new Promise(function(resolve) {
			console.log('then1');
			setTimeout(() => {
				console.log('setTimeout2');
			}, 0);
			resolve();
		}).then(function() {
			console.log('then2');
			setTimeout(() => {
				console.log('setTimeout3');
			}, 0);
		})
	})
	setTimeout(() => {
		console.log('setTimeout4');
	}, 0);
	console.log('end');

如果理解可以理解可以尝试上面较为复杂的代码
依次输出:start->end->then1->then2->setTimeout1->setTimeout4->setTimeout2->setTimeout3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值