js是单线程的,但是浏览器是多线程的,多个线程相互配合以保持同步
var set1=setTimeout(function () {
console.log('s1')
var p0=new Promise(function (resolve, reject) {
resolve(789);
}).then(function (res) {
console.log(res)//123
})
})
var p1 = new Promise(function (resolve) {
console.log('promise1')
resolve(2)
});
var set2=setTimeout(function () {
console.log('s2')
});
p1.then(res => {
console.log('then1')
});
console.log(2)
var p2=new Promise(function (resolve, reject) {
resolve(123);
}).then(function (res) {
console.log(res)//123
})
var p3=new Promise(function (resolve, reject) {
reject(456);
}).catch(function (res) {
console.log(res)//456
})
promise 是个微任务
setTimeout 是个宏任务
第一次执行
set1加入宏任务队列=>p1的console.log(‘promise1’)是同步,所以先输出’promise1’=>
set2加入宏任务队列=>p1.then加入微任务队列接着碰到console.log(2),所以输出2=>接着p2,p3加入微任务队列;
此时的的微任务队列:p1.then,p2.then,p3.catch
此时的的宏任务队列:set1,set2
第一次从上到下执行会输出(1)promise1,(2)2
第二次执行:主线任务执行好后,要先执行微任务队列,队列,顾名思义,先进先出,就像排队一样,此时将p1.then,p2.then,p3.catch全部执行
所以输出then1,123,456;此时的微任务队列已经执行好了,接着要执行宏任务队列
因为setTimeout时间都为0,所以先执行set1,遇到s1,是同步,直接执行,接着又碰到p0.then,放入微任务队列!!!这时已经回到主线程了;
此时的的微任务队列:p0.then
此时的的宏任务队列:set2
第二次从上到下执行会输出(1)s1
第三次执行:开始查询微任务队列,此时只有p0.then,执行,得到789,微任务队列执行完毕,开始查看宏任务队列,此时宏任务队列只剩下set2,所以输出s2
第三次从上到下执行会输出(1)789 (2)s2