在promise产生之前,js 处理异步的方式是使用回调函数,一个回调函数执行完成,进行下一个回调函数。这样会导致层层嵌套,代码不清晰。容易进入回调地狱
promise 有三种状态 pending(进行中),resolved(成功),rejected(失败)
promise的状态是不可逆的
pending--->resolved
或者
pending--->rejected
promise 的参数是一个函数,函数里还有两个参数 resolved rejected
resolved(res) 处理成功的 函数 它传递的参数 会在then方法里输出
rejected(err) 处理失败的函数 它传递的参数 会在 catch方法里输出
let p1 = new Promise((resolved, rejected) => {
let randomVal = Math.random();
if (randomVal > 0.5) {
resolved(randomVal + "成功");
} else {
rejected(randomVal + "失败");
}
})
.then((res) => {
console.log(res)//0.6423699367939153成功
})
.catch((err) => {
console.log(err)//0.3423699367939153失败
});
promise.all 的参数是多个promise函数,直到慢的一个promise执行完毕才返回所有的promise的结果,有一个promise函数崩溃,整个promise就崩溃,所以要慎用
let p1 = new Promise((resolved, rejected) => {
let randomVal = Math.random();
if (randomVal > 0.1) {
resolved(randomVal + "成功");
} else {
rejected(randomVal + "失败");
}
})
let p2 = new Promise((resolved, rejected) => {
let randomVal = Math.random();
setTimeout(() => {
if (randomVal > 0.9) {
resolved("成功" + randomVal);
} else {
rejected("失败" + randomVal);
}
}, 200);
});
Promise.all([p1,p2]).then(resList=>{
console.log(resList)
}).catch(err=>{
console.log("错误err"+err)
}).finally(result=>{
console.log("无论成功或者失败都会执行",result)
})
let p1 = new Promise((resolved, rejected) => {
let randomVal = Math.random();
if (randomVal > 0.1) {
resolved(randomVal + "成功");
} else {
rejected(randomVal + "失败");
}
})
let p2 = new Promise((resolved, rejected) => {
let randomVal = Math.random();
setTimeout(() => {
if (randomVal > 0.9) {
resolved("成功" + randomVal);
} else {
rejected("失败" + randomVal);
}
}, 200);
});
Promise.race([p1,p2]).then(resList=>{
console.log(resList)
}).catch(err=>{
console.log("错误err"+err)
}).finally(result=>{
console.log("无论成功或者失败都会执行",result)
})
setTimeout setInterval
Promise.then Promise.catch Promise.finally
MutationObserver
process.nextTIck(nodejs里的)
同一层的 先执行主线层然后执行微任务,最后执行 宏任务
promise resolved函数执行完毕之后才执行 then的方法
new Promise((resolved,rejected)=>{
console.log("1")
}).then(res=>{
console.log("2")
console.log(res)
})
console.log("4")
错误解法 和错误的思路错误答案 1,4,2 ,1
错误思路,
一般人想 主线程 同步任务走完,然后走 微任务
实际上 promise里没有走resovled函数的时候是不会走 then里的
同理 promise里没有走rejected函数的时候是不会走 catch里的
所以正确的答案是
1 4
resovled函数外边包裹了定时器,得定时器计时结束才能 调用resolved,最后走then
new Promise((resolved, rejected) => {
console.log("1")
setTimeout(() => {
resolved("2");
}, 20);
console.log("3");
}).then((res) => {
console.log("4");
console.log(res);
});
console.log("5");
setTimeout(ele=>{
console.log("6")
},0)
这题直接上正确答案
1,3,5,6,4,2
答案解析
1 promise主体函数的代码,是同步主线程的优先执行
3 同1
5 是主线程
6 和 2 4 res(2) 相比都是定时器里的代码(宏任务),只是 6的延时时间较少,所以优先执行6
4 2 是promise 里的resolved走完之后,执行then 里的 4 res是 resolved("2")里返回的2,所以打印出 2
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 7 6 8 2 4 3 5 9 11 10 12
1 主线程
7 promis主体函数里的代码 主线程
6 process.nextTick 微任务
8 promise resolve函数处理过走 then
2 2345 和 9101112 分别在两个定时器里 由于两个定时器的时间是一致的,所以根据先后i顺序执行,先执行上面的,再执行下边的
2345 2是主线程
4是主线程
3 是微任务
5是微任务
9101112
9 是主线程
11 是主线程
10 是微任务
12 是微任务
总结
当主线程 宏任务 微任务在一起的时候,先执行主线程,然后执行微任务,最后执行宏任务
首先我们了解一下 promise.resolve()是什么的简写
new Promise((resolve)=>{
resolve()
}).then(res=>{
console.log("123")
})
那么一下两个哪个更快呢
setTimeout(ele=>{
console.log("2")
})
Promise.resolve().then(res=>{
console.log("1")
})
将 Promise.resolve().then 转换成上一个写法可以知道 1 是微任务,2 是宏任务,
所以先走1 再走 2
我们接下来再看一题
setTimeout(ele=>{
console.log("1")
Promise.resolve().then(res=>{
console.log("2")
})
})
Promise.resolve().then(res=>{
console.log("3")
setTimeout(ele=>{
console.log("4")
})
})
先走 微任务 3
然后走 上边定时器里的
走主线程 1
走微任务 2
然后走下边的 宏任务
注意
当出现定时器时 按照 延迟时间和创建先后顺序 这两个条件 先后执行定时器,并且只有执行完一个定时器之后,才执行下一个定时器
setTimeout((ele) => {
console.log(1);
setTimeout(() => {
console.log(2);
}, 40);
}, 20);
setTimeout((ele) => {
console.log(3);
}, 30);
这一题
很多人的答案时1 2 3
他们想的是先走完第一个定时器里的再走第二个定时器里的
实际上 第一个嵌套的定时器会产生叠加
2 的执行时间时 20 + 40 也就是 60
而 3 的时间时30 所以时 1 3 2
注意当定时器嵌套时 ,里边的执行时间是会和上边的叠加的
以上是我对宏任务微任务的一些理解,希望对大家能有所帮助,记得点个赞哦