Promise 学习

107 阅读4分钟

本文已参与[新人创作礼]活动, 一起开启掘金创作之路。

Promise是异步编程的一种解决方案。回调地狱终结者。

前言-什么是promise

promise是异步编程的一种解决方案

文档地址:Promise.prototype.then() - JavaScript | MDN (mozilla.org)

应用场景:常见于网络请求(回调地狱)

我们封装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的 1+1=2一样将结果返回。
往往我们会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。
如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。
但是当网络请求非常复杂时,就会出现回调地狱

提示:以下是本篇文章正文内容,下面案例可供参考

一、使用:

  //参数-函数(resolve,reject)
  //resolve,reject本身是一个函数
  new Promise(
      (resolve,reject)=>{
         setTimeout(()=>{
            //Promise是优雅的,这里只请求不处理,去then
            //成功后调用resovle
            resolve("hello world");
            //失败后调用reject
            reject("error message");
         })
      }
  ).then((data)=>{
      //处理接收到的hello world
  }).catch(err =>{
      //失败处理,箭头函数只有一个参数可以省略
  });

二、Promise的三种状态

| sync->同步 | async->异步 |

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending) :初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled) :意味着操作成功完成。
  • 已拒绝(rejected) :意味着操作失败。

执行异步操作后有三种状态

 pending;等待状态,比如正在进行网络请求,或则定时器没有到达时间。
 fulfill;满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
 reject;拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()
//不写catch,在then中传两个参数,一个成功,一个失败
new Promise(
      (resolve,reject)=>{
         setTimeout(()=>{
            //Promise是优雅的,这里只请求不处理,去then
            //成功后调用resovle
            if (SUCCESS) {
              resolve("hello world");
            }
            else {
            //失败后调用reject 注意,只能走一个,因为是主动调用的  
              reject("error message");
            }
         })
      }
  ).then((data)=>{
      //处理接收到的hello world
  },(err)=>{
      //处理失败接收到的error message
  });

三、Promise链式调用

可以看到 .then之后返回的promise对象是全新的,和之前的不一样

image.png

这段代码可能对理解promise链式调用有帮助

image.png

无论then还是catch都可以返回一个promise对象,所以代码是可以进行链式调用的。

咱就是说,在then里面 return一个promise对象,就可以在then后面继续.then()。 显然axios本身就是返回一个promise,所以无限axios吧,不用担心回调地狱

回调地狱演示

image.png promise解决回调地狱演示

image.png

我也不知道2021年为什么写这两句话,跳过跳过
 Promise.resolve():将数据包装成Promise对象,并且在内部回调resolve函数
 Promise.reject():将数据包装成Promise对象,并且在内部调用reject对象

简单示范:

 //原理简单示范
     new Promise((resolve,reject)=>{
         resolve(res);
     }).then((res)=>{
         return new Promise((resolve,reject)=>{
             resolve(res);
         }).then(res=>{

         })
     })

高级写法:

//升级:
         new Promise((resolve,reject)=>{
         resolve(res);
         }).then((res)=>{
             return  Promise.resolve()
         }).then(res=>{

         });

image.png

总结promise链式调用

image.png

扩展 async await 使用

学习文档地址:async 函数 - JavaScript | MDN (mozilla.org)

async 和 await 关键字让我们可以用一种更简洁的方式写出基于 Promise 的异步行为,而无需刻意地链式调用 promise

async 函数可能包含 0 个或者多个 await 表达式。await 表达式会暂停整个 async 函数的执行进程并出让其控制权,只有当其等待的基于 promise 的异步操作被兑现或被拒绝之后才会恢复进程。

image.png

使用 async await后的错误捕获

image.png

image.png

四、Promise的all方法使用

两个以及以上 的请求。要求都完成,

都完成会调用then

如果有一个失败,则调用catch

Promise.all([

       //第一个promise
       new Promise((resolve,reject)=>{
           resolve();
       }).then(),

       //第二个promise
       new Promise((resolve,reject)=>{
           resolve()
       }).then();

   ]).then(results =>{
       //等两个都完成,使用results[0],results[1]
   })

image.png

总结

new一个promise对象,箭头函数大妙用,resolve成功调用,reject失败调用。 成功跳到.then,失败跳到.catch。 当然,也可以直接.then里面传两个箭头函数,一个成功res,一个失败err。