一、js的内存模型
二、js代码执行机制:
-
-
主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
-
三、宏任务与微任务:
-
-
MicroTask(微观任务) process.nextTick, Promise, Object.observe, MutationObserver
-
案例一:(在主线程上添加宏任务)
先看代码:一个打印,一个定时器,一个打印
因为定时器是异步操作,又是宏任务,所以先执行第一个打印,接着将setTimeout放入宏任务队列,接着执行第二个打印,再执行宏任务队列中的setTimeout
案例二:(在主线程上添加微任务)
console.log(1) new Promise(function(resolve,reject){ console.log('2') resolve() }).then(function(){ console.log(3) }) console.log(4) //1 2 4 3
先看代码:一个打印,一个new promise,一个promise.then,一个打印
因为new promise会立即执行,promise.then是异步操作且是微任务
所以,先执行第一个打印,执行new Promise,将promise.then放入微任务队列,接着执行第二个打印,再执行微任务队列中的promise.then
案例三:(红任务中创建微任务)
console.log('1'); setTimeout(function () { console.log('2'); new Promise(function (resolve) { console.log('3'); resolve(); }).then(function () { console.log('4') }) },0) new Promise(function (resolve) { console.log('5'); resolve(); }).then(function () { console.log('6') }) setTimeout(function () { console.log('7'); new Promise(function (resolve) { console.log('8'); resolve(); }).then(function () { console.log('9') }) console.log('10') },0) console.log('11')
先看代码:一个打印,第一个定时器,一个new promise,一个promise.then,第二个定时器,一个打印
定时器是异步操作,又是宏任务,promise.then是异步操作且是微任务
所以,先执行第一个打印(1),将第一个定时器放入宏任务队列,执行new Promise(5),将promise.then放入微任务队列,将第二个定时器放入宏任务队列,执行打印(11);
主线程上的代码执行完毕后,看是否有微任务?此时:微任务队列中有一个promise.then,执行它(6);微任务执行完毕看宏任务队列;
此时宏任务队列中两个定时器,延时都是0秒,所以按顺序执行就ok,先执行第一个定时器
第一个定时器中:一个打印,一个mew promise,一个promise.then(微任务);(宏任务中包含微任务,一定要将宏任务中的微任务执行完,再去执行下一个宏任务)
先执行打印(2),再执行new promise(3),再执行promise.then(4);第一个宏任务执行完,执行第二个宏任务(第二个定时器)
第二个定时器中:一个打印,一个new promise,一个promise.then(微任务),一个打印
先执行第一个打印(7),再执行new promise(8),再执行第二个打印(10),在执行promise.then(9)
案例四:(微任务中创建宏任务)
new Promise((resolve) => { console.log("1") resolve() }).then(() => { console.log("2") setTimeout(() => { console.log("3") },0) }) setTimeout(() => { console.log("4") },1000) console.log("5") //1 5 2 3 4
先看代码:一个new promise,(一个then,一个定时器(0秒)),一个定时器(1秒),一个打印 微任务中有宏任务,则将宏任务放入宏任务队列任务中
先执行new promise(1),再将promise.then放入微任务队列,将定时器放入宏任务队列(0秒),将定时器放入宏任务队列(1秒),执行打印(5)
接着看微任务队列,执行promise.then(2);微任务队列中都执行完再看宏任务队列
宏任务队列中两个定时器,一个延时0秒,一个延时1秒,所以先执行延时0秒的那个
第一个定时器:执行(3);
第二个定时器:执行(4)