Skip to content
大纲

宏任务和微任务

在NodeJS中process.nextTick微任务的优先级高于Promise.resolve微任务

事件循环

宏任务: setTimeout,setInterval,Ajax,DOM事件 I/O UI交互事件、postMessage、MessageChannel、setImmediate(node.js环境中)

微任务:Promise.then/catch async/await Object.observe MutationObserve precess.nextTick(node.js环境)

  • 微任务 macro ˈmækroʊ (miekou)

  • 宏任务 micro 'maɪkrəʊ (maikou) 微任务是插队宏任务

优先级

new Promise() > process.nextTick > Promise.resolve(then) > setTimeout

微任务

process.nextTick > Promise.resolve

题目练习

题目1 (初级)

js
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')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

题目1-1 (初级)

js
console.log('aaa');

setTimeout(()=>console.log('t1'), 0);
(async ()=>{
  console.log(111);
  await console.log(222);
  console.log(333);

  setTimeout(()=>console.log('t2'), 0);
})().then(()=>{
  console.log(444);
});

console.log('bbb');

题目2 (中级)

js
console.log('第1层,script start')
async function async1() {
    // 1
    await async2()
     console.log('第3层 async1 end')
     }
async function async2() {
    console.log('第1-1层 aFsync2 end')
    return Promise.resolve().then(()=>{
        console.log('第2层 async2 end1')
    })
}
async1()

setTimeout(function() {
    console.log('倒数第1层 setTimeout')
}, 0)

new Promise(resolve => {
    console.log('第1层,Promise')
    resolve()
})
.then(function() {
    console.log('第2层 promise1')
})
.then(function() {
    console.log('第3层 promise2')
})

console.log('第1层 script end')

题目2-1(中级)

js
console.log('Script开始')
setTimeout(() => {
  console.log('第一个回调函数,宏任务1')
  Promise.resolve().then(function() {
    console.log('第四个回调函数,微任务2')
  })
}, 0)

setTimeout(() => {
  console.log('第二个回调函数,宏任务2')
  Promise.resolve().then(function() {
    console.log('第五个回调函数,微任务3')
  })
}, 0)
Promise.resolve().then(function() {
  console.log('第三个回调函数,微任务1')
})
console.log('Script结束')

题目3-1(高级)

js
console.log("第1层",1)

async function async1() {
    // 1层
    await async2()
    console.log("第4层",2)
}
async function async2() {
    console.log("第1-1",3)
    return Promise.resolve().then(()=>{
        console.log("第2层",4)
    }).then(()=>{
        console.log("第3层",5)
    })
}
async1()

setTimeout(function() {
    console.log("倒数第1",6)
}, 0)

new Promise(resolve => {
    console.log("第1层",7)
    resolve()
})
.then(function() {
    console.log("第2层",8)
    Promise.resolve().then(()=>{
        console.log("第2-1",11)
    })
})
.then(function() {
    console.log("第3层",9)
    Promise.resolve().then(()=>{
        console.log("第3-1层",12)
    })
})

console.log("第1层",10)

题目3-2(与题目3类似)

js
console.log("第1层",1)

async function async1() {
    await async2()
    console.log("第3层",2)
}
async function async2() {
    console.log("第1-1层",3)
    return Promise.resolve().then(()=>{
        console.log("第2层",4)
    })
}
async1()//第1层

setTimeout(function() {
    console.log("倒数第1",6)
}, 0)

new Promise(resolve => {
    console.log("第1层",7)
    resolve()
})
.then(function() {
    console.log("第2层",8)
    Promise.resolve().then(()=>{
        console.log("2-1",11)
    })
})
.then(function() {
    console.log("第3层",9)
    Promise.resolve().then(()=>{
        console.log("3-1",12)
    })
})

console.log("第1层",10)

题目3-1精简版本1

js
async function async1() {
    await async2()
}
async function async2() {
     return Promise.resolve().then(()=>{}).then(()=>{ console.log("第3层",5) })
}
async1()
new Promise(resolve => {
    resolve()
}) .then(function() {
    console.log("第2层",8)
    Promise.resolve().then(()=>{
        console.log("2-1",11)
    })
})

题目3-1精简和翻译版本1

js
//第1道
new Promise(resolve =>{ Promise.resolve().then().then(()=> console.log("第5层",5) ) })
new Promise(resolve =>resolve()).then(()=> {
    console.log("第3层")
    Promise.resolve().then(()=> console.log("2-1") )
})
js
// 第2道
async function async1() {
    await  Promise.resolve().then().then(()=>{ console.log("第5层1",5)
     })
}
async1()
new Promise(resolve =>resolve()).then(()=>{
    console.log("第2层",8)
    Promise.resolve().then(()=>{ console.log("第5层2",11) })
})

题目3-1精简版本3 魔改版本

js
// 第1道
new Promise(resolve =>resolve()).then(()=> {
   Promise.resolve().then().then(()=>{ console.log("第5层-1")} )
})
new Promise(resolve =>resolve()).then(()=> {
    console.log("第3层",)
    Promise.resolve().then(()=> {console.log("4-1")} ).then(()=>{ console.log("第5-2层") })
}).then(()=>{
    // 4层
console.log("第4-2层")
}).then(()=>{
    //5层 
console.log("第5-3层")
})

精简版本2

js
async function async1() {
    await async2()
}
async function async2() {
     return Promise.resolve().then(()=>{
         console.log("第2层")
    })
}
async1()
new Promise(resolve => {
    resolve()
}) .then(()=> {
    console.log("第2层")
    Promise.resolve().then(()=>{
        console.log("2-1")
    })
})
.then(()=> {
    console.log("第3层")
    Promise.resolve().then(()=>{
        console.log("第3层3-1")
    })
})
js
Promise.resolve().then(() => {
  console.log("第2层",0);
  return Promise.resolve(4)
}).then(res => {
  console.log("第5层",res)
})

Promise.resolve().then(() => {
  console.log("第2层",1);
}).then(() => {
  console.log("第3层",2);
}).then(() => {
  console.log("第4层",3);
}).then(() => {
  console.log("第5层",5);
}).then(() =>{
  console.log("第6层",6);
})
js
Promise.resolve().then(() => {
    console.log(0);
    return {
        then(resolve){


            resolve(4)
            
            }
            
            };
}).then((res) => {
    console.log(res)
})

题目

js
console.log(1); //第1层

async function fn1() {
  console.log(2);//第1层
  await fn2();
  console.log(4);//第5层
}

new Promise((resolve, reject) => {
  console.log(7);//第1层
  resolve(8);
}).then((res) => {
  console.log(res)//第3层=>8
})

fn1();//第1层

async function fn2() {
  console.log(3);//第2层
  setTimeout(() => {
    console.log(6);//宏任务单独为一层,第一层
  });
  const res = await fn3();
  console.log(res);//第5层=>10
}

function fn3() {
  console.log(5);//第3层
  return new Promise((resolve, reject) => {
    console.log(9);//第3层
    resolve(10);//3+2
  });
}
js
console.log(1)

function fn1() {
  console.log(2)
  fn2().then((res) => {
    console.log(res)
  })
  console.log(3)
}

async function fn2() {
  return await Promise.resolve(4)
}

function fn3(params) {
  setTimeout(() => {
    console.log(5)
    Promise.resolve().then(() => {
      console.log(6)
    })
  }, 1000)
}
fn1()

fn3()
setTimeout(() => {
  console.log(7)
}, 1000)

参考文章

oschina-宏任务和微任务

V8源码补充篇 从一道让我失眠的 Promise 面试题开始,深入分析 Promise 实现细节

juejin传送门

事件循环