在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
注意当定时器嵌套时 ,里边的执行时间是会和上边的叠加的
以上是我对红任务微任务的一些理解,希望对大家能有所帮助,记得点个赞哦