返回顶部
热门问答 更多热门问答
技术文章 更多技术文章

Promise与它的四个小伙伴resolve、reject、all、race

[复制链接]
北极孤星的泪 显示全部楼层 发表于 2022-4-15 16:19:54 |阅读模式 打印 上一主题 下一主题

登录网站,浏览更多精彩内容

您需要 登录 才可以下载或查看,没有账号?加入我们

x
要搞清楚执行顺序首先记住一句话:同步 => 异步 => 回调Promise 的结构

在后台打印一下console.dir(Promise)

1.png

Promise其实是一个构造函数,它有resolve,reject,race等静态方法;

Promise的原型(prototype)上有catch,then,finally方法;

Promise 与resolve

reslove之后,promise函数一旦有了结果(比如执行了then方法)就会开启一个微任务执行回调函数,微任务的优先级是很高的;

那么Promise将执行reslove(成功)状态后的函数

  1. let p = new Promise(function(reslove,reject){
  2.     reslove('成功1')  //状态由等待变为成功,传的参数作为then函数中成功函数的实参
  3. })

  4. p.then((data)=>{
  5.     console.log('成功2+'+data)
  6. },(err)=>{
  7.     console.log('失败2+'+err)
  8. }).catch((e)=>{
  9. console,log("失败3",e)
  10. })
复制代码
reslove(‘成功1’)中的成功1 作为then中的结果data输出
结果(注意这里的结果是一行展示,不是换行)=>成功2+成功1Promise 与reject将示例1的resolve(“成功1”)改成reject(‘失败1’) ,
那么Promise将执行reject(失败)状态后的函数
  1. let p = new Promise(function(reslove,reject){
  2.     reject('失败1')  //状态变为失败,执行的err中的回调函数。
  3. })

  4. p.then((data)=>{
  5.     console.log('成功2+'+data)
  6. },(err)=>{
  7.     console.log('失败2+'+err)
  8. }).catch((e)=>{
  9. console,log("失败3",e)
  10. })
复制代码
结果=>失败2+失败1
Promise 与 setTimeout
  1.         setTimeout(() => {
  2.           console.log(0)
  3.         })
  4.         
  5.         new Promise(resolve => {
  6.           resolve(1)
  7.           Promise.resolve().then(t => {
  8.             console.log(2)
  9.           })
  10.           console.log(3)
  11.         })
  12.         .then(t => {
  13.           console.log("成功+"t)
  14.         })
  15.         
  16.         console.log(4)
复制代码
结果:
1.png
这是为什么呢???是不是一脸懵逼了,为什么2先执行???
为什么先输出3,然后4
这是因为执行顺序中:同步 => 异步 => 回调; console.log(3)和console.log(4)是同步
resolve是异步,这也解释了,为什么“成功”后面跟着1
setTimesout是回调,放最后,所以0在最后;
最后解释为什么2先打印
因为reslove后,promise函数一旦有了结果(比如执行了then方法)就会开启一个微任务执行回调函数,微任务的优先级是很高的;
resolve在没有结果的状态下是不会执行的;上述代码中,在执行 resolve(1)的时候并没有.then(t =>{console.log("成功+"t)}),所以不会立即立即打印,成功+1;
resolve(1)之后跟着一个嵌套的Promise.resolve().then(t => { console.log(2) }),并且,resolve紧挨着.then(t => { console.log(2) }),那么嵌套的Promise就有结果,先执行回调函数console.log(2);所以先输出2;
Promise与all
  1. function num(x){
  2.     let p= new Promise((resolve,reject)=>{
  3.         setTimeout(()=>{
  4.             resolve(x,console.log(x))
  5.         },5000)
  6.     })
  7.     return p
  8. }
  9. Promise.all([num(1), num(2), num(3)])
  10.   .then(res => console.log(res))
复制代码

//简写为以下,不熟练的还是老实一点,没错就是本人
  1. function num(x) {
  2.     const p = new Promise(r => setTimeout(() => r(x,console.log(x)), 5000))
  3.     return p
  4. }
  5. Promise.all([num(1), num(2), num(3)])
  6.   .then(res => console.log(res))
复制代码
分析:
Promise.all([num(1),num(1),num(1)])主要用于并行执行(并行!!!同时执行,没有先后顺序)。比如加载多个静态文件,等全部加载完成之后再执行.then()中的语句,展示出来。
缺点:如果有一个图片请求异常,就gg,并不会调用Promise.all 的then里面的语句。
执行结果:
5秒之后下面的1,2,3是同时打印的,因为并行!!!
1.png
Promise与race(race:赛跑,不是米饭!!!)
是不是只有我一个人第一眼看到这个单词,脑子里浮现的是一碗米饭?
  1. function num(x) {
  2.     const p = new Promise(r => setTimeout(() => r(x,console.log(x)), 5000))
  3.     return p
  4. }
  5. Promise.race([num(1), num(2), num(3)])
  6.   .then(res => console.log('race:'res))
复制代码
分析:
只要有一个结果了,我就执行下一步。
怎么用呢,如果有一个图片请求超时了,race还是能继续执行。如果all()的话就会卡住。
执行顺序:
1.png
Promise与then 与catch
promise 只会执行一次,无论之后调用了多少次then()、catch(),为Promise只会执行一次。
换句话说:promise 内部状态一经改变,并且有了一个值,那么后续无论怎么调用then().catch(),Promise内部状态都不会改变。
  1. const promise = new Promise((resolve, reject) => {
  2.   setTimeout(() => {
  3.     console.log('timer')
  4.     resolve(Date(Date.now()))
  5.   }, 1000)
  6. })
  7. const start = Date.now();
  8. promise.then(res => {
  9.   console.log(res)
  10. })
  11. promise.then(res => {
  12.   console.log(res)
  13. })
复制代码

分析
promise.then运行Promise,虽然promise.then虽然是异步,但是Promise里面没有更新状态所以先不会执行。所以Promise里面的setTimeout先执行,一秒后先打印timer。
resolve(Date.now()之后,因为Promise只会执行一次。所以Date(Date.now())永远都是第一次执行promise.then()返回的resolve值Tue Jun 09 2020 14:18:21 GMT+0800 (中国标准时间)。
第二次执行promise.then,res值还是Tue Jun 09 2020 14:18:21 GMT+0800 (中国标准时间)
执行结果:
1.png
Promise与return
Promise函数中then()或者catch()中return一个非Promise的值都会包裹成Promise本身。扩展一下,如果在then或者catch中return Promise函数本身就会造成死循环
  1. new Promise((resolve,reject)=>{
  2.         resolve('success')
  3. }).then(res=>{
  4.         console.log('res1',res)
  5. }).then(res=>{
  6.         return 1
  7. }).then(res=>{
  8.         console.log('res2',res)
  9. })
复制代码
分析:
第一个then(),console.log(‘res1’,res)正常执行,res1 success
第二个then(),return了非Promise值1,那么return 1会被包裹成 Promise.resolve(‘1’),所以res值改变为1
第二个then(),执行console.log(‘res2’,res),打印res 2
执行结果:
1.png
死循环写法:
  1. const promise = Promise.resolve().then(() => {
  2.   return promise;
  3. })
  4. promise.catch(console.err)
复制代码
Promise与值透传
这个世界真的是太复杂了!!!
学吧!!!
Promise的then()或者catch()中的参数只能是函数()=>{},多层then()catch()叠加,如果不是函数的话,往上层找then中返回函数的,直到找到返回函数的为止。返回Promise中resolve或者reject的值。
  1. Promise.resolve(1)
  2. .then(()=>{return 2})
  3. .then(()=>{return Promise.resolve(3)})
  4. .then(console.log)
复制代码
执行结果: 3
  1. Promise.resolve(1)
  2. .then(()=>{return 2})
  3. .then(Promise.resolve(3))
  4. .then(console.log)
复制代码
执行结果: 2
  1. Promise.resolve(1)
  2. .then(2)
  3. .then(Promise.resolve(3))
  4. .then(console.log)
复制代码
执行结果: 1
商乾电商学院,中国最大的电商资源交流基地!
商乾全球电商人、电商交流学习与电商实战技术分享、电商爬虫、生活交流专业网站
  • 官方手机版

  • 微信公众号

  • 商务合作