promise async await

本文深入探讨了Promise的使用,包括其三种状态、链式调用和Promise.all的两种写法。同时,介绍了async/await的异步操作及其错误处理方法,包括then-catch、try-catch以及结构赋值的处理方式。文章旨在帮助开发者更好地理解和应用异步编程。
摘要由CSDN通过智能技术生成

一、定义

  • ES6中重要和好用的特性
  • 是异步编程的一种解决方案
  • resolve , reject 是函数
  • 链式编程

二、什么时候使用

  • 一般在有异步操作时,使用Promise对异步操作的封装
  • new ----->构造函数(1、保存一些状态信息 2、执行传入的函数)
  • 在执行传入的回调函数时,会传入两个参数。resolve 、reject 本身又是函数

可以嵌套:(简单嵌套)
image.png

三、Promise的三种状态

  • pending:等待状态,比如正在进行网络请求,或者定时器没有到时间;
  • fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
  • reject:拒绝状态,当我们主动调用reject时,就处于该状态,并且会回调.catch()
//也可以将 resolve reject 调用的放在一起
//如下 可以都放在了then里面 用逗号隔开
 new Promise((resolve, reject) => {
        resolve("成功");
        // reject("失败");
      }).then(
        (data) => {
          console.log(data);
        },
        (error) => {
          console.log(error);
        }
      );
    },
// bad
promise
  .then(function(data) {
    // success
  }, function(err) {
    // error
  });

// good 要这么写
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

四、链式调用

4.1考虑的是每层都是正确的情况

除了前面2、的简单嵌套
还可以对 对前面数据的处理 再进行下一步

 new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("111");
        }, 1000);
      })
        .then((res) => {
          //1、第一次自己处理代码
          console.log(res, "第一层的处理代码"); //输出结果111
          // 2、第一次对结果处理
          return new Promise((resolve) => {
            resolve(res + 222);
          });
        })
        .then((res) => {
          //1、第二次自己处理代码
          console.log(res, "第二层的处理代码"); //输出结果111222
          //2、第二次对结果处理
          return new Promise((resolve) => {
            resolve(res + 333);
          });
        })
        .then((res) => {
          //1、第三次自己处理代码
          console.log(res, "第三层的处理代码"); //输出结果111222333
          //2、第三次对结果进行处理
          return new Promise((resolve) => {
            resolve(res + 444);
          });
        })
        .then((res) => {
          console.log(res, "第四层的处理代码"); //输出结果111222333444
        });
      

上面的代码可以简写,如下:

  //简写  new Promise(resolve => resolve(结果))
 new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("111");
        }, 1000);
      })
        .then((res) => {
          //1、第一次自己处理代码
          console.log(res, "第一层的处理代码");
          // 2、第一次对结果处理
          // return new Promise((resolve) => {
          //   resolve(res + 222);
          // });
          return Promise.resolve(res + 222);
        })
        .then((res) => {
          //1、第二次自己处理代码
          console.log(res, "第二层的处理代码");
          //2、第二次对结果处理
          // return new Promise((resolve) => {
          //   resolve(res + 333);
          // });
          return Promise.resolve(res + 333);
        })
        .then((res) => {
          //1、第三次自己处理代码
          console.log(res, "第三层的处理代码");
          //2、第三次对结果进行处理
          // return new Promise((resolve) => {
          //   resolve(res + 444);
          // });
          return Promise.resolve(res + 444);
        })
        .then((res) => {
          console.log(res, "第四层的处理代码");
        });   

上面的代码还可以简写,如下:

 //还可以更简洁 省略掉Promise.resolve
      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("111");
        }, 1000);
      })
        .then((res) => {
          //1、第一次自己处理代码
          console.log(res, "第一层的处理代码");
          // 2、第一次对结果处理
          return res + 222;
        })
        .then((res) => {
          //1、第二次自己处理代码
          console.log(res, "第二层的处理代码");
          //2、第二次对结果处理
          return res + 333;
        })
        .then((res) => {
          //1、第三次自己处理代码
          console.log(res, "第三层的处理代码");
          //2、第三次对结果进行处理
          return res + 444;
        })
        .then((res) => {
          console.log(res, "第四层的处理代码");
        });

4.2 有一层出现错误(reject)的写法

// 前面考虑的是 每一层都是成功的情况 如果中间有一层是执行失败呢?
// 输出第一次自己处理代码的饿结果和reject的结果
      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("111");
        }, 1000);
      })
        .then((res) => {
          //1、第一次自己处理代码
          console.log(res, "第一层的处理代码"); //输出结果111
          // 2、第一次对结果处理
          return new Promise((resolve, reject) => {
            // resolve(res + 222);
            reject("err,对结果第一次处理 出现错误"); //错误结果
          });
        })
        .then((res) => {
          //1、第二次自己处理代码
          console.log(res, "第二层的处理代码");
          //第二次对结果处理
          return new Promise((resolve) => {
            resolve(res + 333);
          });
        })
        .then((res) => {
          //1、第三次自己处理代码
          console.log(res, "第三层的处理代码");
          //2、第三次对结果进行处理
          return new Promise((resolve) => {
            resolve(res + 444);
          });
        })
        .then((res) => {
          console.log(res, "第四层的处理代码");
        })
        .catch((err) => {
          console.log(err);
        });

前面代码的简写:

    //前面中间有错误的处理方法一样有简写
      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("111");
        }, 1000);
      })
        .then((res) => {
          //1、第一次自己处理代码
          console.log(res, "第一层的处理代码"); //输出结果111
          // 2、第一次对结果处理
          // return Promise.reject("err message"); //reject简写
          throw "error message"; //这种写法也是一样的

        })
        .then((res) => {
          //1、第二次自己处理代码
          console.log(res, "第二层的处理代码");
          //第二次对结果处理
          return promise.resolve(res + 333);
        })
        .then((res) => {
          //1、第三次自己处理代码
          console.log(res, "第三层的处理代码");
          //2、第三次对结果进行处理
          return Promise.resolve(res + 444);
        })
        .then((res) => {
          console.log(res, "第四层的处理代码");
        })
        .catch((err) => {
          console.log(err);
        });

五、promise.all 的使用

(1)写法1

     //在两个Promise请求全部得到结果后 才then
      //返回的results是数组,数组[0]是第一个promise返回的数据;数组[1]是第二个Promise返回的数据
      Promise.all([
        new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve({
              name: "第一个请求返回的数据!",
              message: "返回的时间是两秒后",
            });
          }, 2000);
        }),
        new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve({
              name: "第二个请求返回的数据",
              message: "返回的时间是一秒后",
            });
          }, 1000);
        }),
      ]).then((results) => {
        console.log(results);
      });

返回的结果:
image.png

(2)写法2

下面的方法会简洁一点:
      let p1 = new Promise((resolve, reject) => {
        let math1 = Math.ceil(Math.random() * 10);
        if (math1 > 5) {
          resolve(math1);
        } else {
          reject(math1);
        }
      });

      let p2 = new Promise((resolve, reject) => {
        let math2 = Math.ceil(Math.random() * 10);
        resolve(math2);
      });

      let p3 = new Promise((resolve, reject) => {
        let math3 = Math.floor(Math.random() * 10 + 1);
        resolve(math3);
      });

      const p = Promise.all([p1, p2, p3]);
      p.then((data) => {
        console.log("promise.all resolve 返回的结果", data);
        // (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
      }).catch((error) => {
        console.log("promise.all reject 结果", error);
        // (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
      });
      // 返回的可能结果:
      // promise.all resolve 返回的结果 (3) [8, 3, 9]
      // promise.all reject 结果 3

六. async/await

基本写法:getInfs() 正常调用这个方法就好
image.png

  • asyncawait 是成对出现的
  • 正常情况:await 命令后面是一个Promise对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
  • 另一种情况是,await命令后面是一个thenable对象(即定义了then方法的对象),那么await会将其等同于 Promise 对象。
  • async 的异步操作 要如下写法2 这样写。这样不会由于串联造成的堵塞而浪费时间
    fun1() {
      return new Promise((resolve) => {
        setTimeout(() => {
          let data = [1, 2, 3, 4, 5];
          resolve(data);
        }, 2000);
      });
    },
    fun2() {
      return new Promise((resolve) => {
        setTimeout(() => {
          let data = [1, 3, 5, 7];
          resolve(data);
        }, 1000);
      });
    },
    fun3() {
      return new Promise((resolve) => {
        setTimeout(() => {
          let data = [2, 4, 6, 8];
          resolve(data);
        }, 3000);
      });
    },
    async totalTask() {
      console.log("开始");
      // -------------------- 写法1 ------------------------
      // await this.fun1().then((res) => {
      //   console.log("fun1的返回值是:", res);
      // });

      // await this.fun3().then((res) => {
      //   console.log("fun3的返回值是:", res);
      // });

      // await this.fun2().then((res) => {
      //   console.log("fun2的返回值是:", res);
      // });

      // -------------------- 写法2 --------------------------
      // 因为写法1的话 要等到fun1 完成才执行fun2 再执行fun3
      // 这样写是为了 串行 而造成的堵塞 而浪费时间
      let data1 = this.fun1();
      let data2 = this.fun2();
      let data3 = this.fun3();

      await data1.then((res) => {
        console.log("111111111", res);
      });
      await data3.then((res) => {
        console.log("3333333333", res);
      });
      await data2.then((res) => {
        console.log("222222222222", res);
      });
       console.log("await data1-------------:", await data1);// [1, 2, 3, 4, 5]
      console.log("data1-------------:", data1); //输出promise对象 如下:
//Promise {<fulfilled>: Array(5)}
//[[Prototype]]: Promise
//[[PromiseState]]: "fulfilled"
//[[PromiseResult]]: Array(5)


    async getBooksByPrice(price) {
      let bookss = await this.getAllBooks(); //等这一步完成 执行下面的东西
      return {
        books: bookss.filter((v) => v.price > price),
      };
    },
    btnClick() {
      this.getBooksByPrice(100).then((v) => console.log("v", v));
    },

七、async await 的错误处理方法

7.1 then - catch

    async click() {
      console.log("start");
      const result = await this.Success();

      console.log("result:", result);

      await this.UnSuccess()
        .then((data) => {
          console.log("unSuccess result 信息:", data);
        })
        .catch((err) => {
          console.log("UnSuccess error 信息:", err.message);
        })
        .then(() => {
          console.log("end end");
        });

      console.log("end");
    },

    Success() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("Run Success");
        }, 1000);
      });
    },

    UnSuccess() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error("Run Error"));
        }, 500);
      });
    },

7.2 try - catch

    async click3() {

      try {
        console.log("start------------------");
        let result1 = await this.UnSuccess(); //1
        console.log("result1:", result1); //1 没有执行
      } catch (err) {
        console.log("发生错误!");
        console.log(err.message);
      }

      try {
        let result2 = await this.Success(); //2
        console.log("result2:", result2); //2
      } catch (err) {
        console.log("发生错误!");
        console.log(err.message);
      }

      console.log("end");

    },

    Success() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("Run Success");
        }, 1000);
      });
    },

    UnSuccess() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error("Run Error"));
        }, 500);
      });
    },

7.3 then - catch 结构赋值

  async click1() {
      console.log("start--------------");
      const [err, result] = await this.Success()
        .then((result) => [null, result])
        .catch((err) => [err, null]);

      if (err) {
        console.log("获取到的错误信息为:", err);
      } else {
        console.log("results:", result);
      }

      console.log("===================");

      const [errs, results] = await this.UnSuccess()
        .then((res) => [null, res])
        .catch((err) => [err, null]);

      if (errs) {
        console.log("获取的错误信息:", errs);
        return;
      }
      console.log("results", results);

      console.log("end--------------");
    },

    Success() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("Run Success");
        }, 1000);
      });
    },

    UnSuccess() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error("Run Error"));
        }, 500);
      });
    },

7.4 封装 then - catch 结构赋值

   async click() {
      console.log("start----------------");

      const [err, result] = await this.AsyncHandling(this.UnSuccess);

      if (err) {
        console.log("发生错误了");
        console.log(err);
      } else {
        console.log("result:", result);
      }

      const [err2, result2] = await this.AsyncHandling(this.Success);
      if (err2) {
        console.log("又发生错误了");
        console.log(err2);
      } else {
        console.log("result2:", result2);
      }

      console.log("end");
    },

    AsyncHandling(asyncFn) {
      return asyncFn()
        .then((result) => [null, result])
        .catch((err) => [err, null]);
    },

    Success() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("Run Success");
        }, 1000);
      });
    },

    UnSuccess() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error("Run Error"));
        }, 500);
      });
    },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值