在js所有任务中,分为两种,一种是同步任务,一种是异步任务。
同步任务是指,在js的主线程中执行的任务,只有前一个任务执行完毕,下一个任务才会开始执行。
异步任务是指,不在主线程,而是在任务队列中的任务。只有主线程中的任务全部执行完毕,才会在任务队列中按顺序取出任务放入主线程再执行。
而任务队列中存放的是有了结果的异步函数
异步执行的机制就是:
1、所有同步任务都在主线程上执行
2、主线程外由一个任务队列,存放着有了结果的异步函数。
3、当主线程中的所有同步任务执行完毕,就会读取任务队列中的异步任务,按顺序取出异步任务放入主线程中执行
4、只要任务队列中一直存在任务,就会不断的重复第三步
总所周知,Promise是异步的,但是这里的异步是指他的.then()和.catch()方法,Promise本身还是同步的,所以当执行一个函数时,会先执行new Promise()的同步方法,再执行回调resolve或者是reject。
执行顺序:
同步(Promise)>异步(微任务(process.nextTick、Promise.then、Promise.catch、resolve、reject)>宏任务(setTimeout、setInterval、setImmediate))
只有同步任务执行完了才会去执行异步任务,哪怕异步任务已经到时间了
小试牛刀1:
console.log(1);
Promise.resolve().then(()=>{
console.log(2);
Promise.resolve().then(()=>{
console.log(3)
Promise.resolve().then(()=>{
console.log(4);
});
})
})
setTimeout(()=>{
console.log(5);
},0)
Promise.resolve().then(()=>{
console.log(6);
})
setTimeout(()=>{
console.log(7);
})
输出结果是:1 2 6 3 4 5 7
先执行所有的同步任务,再执行异步任务中的微任务,最后执行异步任务中的宏任务
小试牛刀2:
setTimeout(()=>{
new Promise((res,rej)=>{
console.log('异步宏任务Promise'); //4
res();
}).then(()=>{
console.log('异步微任务then'); //6
})
console.log('异步宏任务'); //5
})
new Promise((res,rej)=>{
console.log('同步任务Promise'); //1
res();
}).then(()=>{
console.log('异步任务then'); //3
})
console.log('同步任务宏任务'); //2
输出结果:
小试牛刀3:
setTimeout(()=>{
console.log('异步1任务time1'); //5 5
new Promise((res,rej)=>{
console.log('异步1宏任务promise'); //6 6
setTimeout(()=>{
console.log('异步1任务time2'); //9 9
})
res()
}).then(()=>{
console.log('异步1微任务then'); //7 7
})
})
console.log('主线程宏任务'); //1 1
setTimeout(()=>{
console.log('异步2任务time2'); //8 8
})
new Promise((res,rej)=>{
console.log('宏任务Promise'); //2 2
res();
// rej()
}).then(()=>{
console.log('微任务then'); //4 4
}).catch(()=>{
console.log('微任务catch');
})
console.log('主线程宏任务2'); //3 3
输出结果: