Promise的使用

Promise是JavaScript中处理异步操作的重要工具,它解决了回调地狱的问题,提供了链式调用和错误处理的优雅方式。本文详细介绍了Promise的基本概念、状态转换、链式调用以及Promise.all方法的使用,帮助开发者更好地理解和运用Promise进行复杂异步任务的管理。

认识Promise

什么是Promise?

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

什么时候会处理异步事件呢?

很常见的场景就是网络请求了,封装一个网络请求的函数时,不能立即得到结果,往往会传入另一个函数,在请求成功后,将数据通过传入的函数回调出去。

但是当网络请求非常复杂时,就会出现回调地狱

网络请求的回调地狱

比如下面的场景:

  • 通过url1,获取数据data1,data1中包含下一个请求的url2
  • 通过data1取出url2,获取数据data2,data2中包含下一个请求的url3
  • 通过data2取出url3,获取数据data3,data3中包含下一个请求的url4
  • 通过data3取出url4,获取到最终的数据data4

上面的代码,正常情况下,不会有问题,可以正常运行并得到最终数据

但是,这样的代码不仅难看,还不利于维护,简直像地狱

这时,就希望有一种优雅的方式来进行这种异步操作

如何做呢?就是使用Promise,它可以以一种非常优雅的方式来解决这个问题

Promise的基本使用

定时器的异步事件

用定时器模拟异步事件:

  • 假设data是从网络请求得到的数据
  • console.log是处理方式

换成Promise代码

这个例子看上去就感觉是多此一举,没必要,首先,Promise的代码明显比上面的代码复杂,其次,Promise代码中又包含resolve、reject、then、catch,这又是什么东西呢?

定时器异步事件解析

读一读上面的代码到底做了什么?

  • new Promise很明显是创建了一个Promise对象
  • 小括号中 ((resolve, reject) => {}),也很明显是一个函数
    • resolve和reject它们也是函数,通常情况下,会根据请求数据的成功和失败来决定调用哪一个
    • 如果成功,调用resolve(message),后续的then会被回调
    • 如果失败,调用reject(error),后续的catch会被回调

Promise的三种状态

  • pending:等待状态,比如正在进行网络请求,或者定时器没到时间
  • fulfill:满足状态,当主动回调resolve时,就处于该状态,并且回调 .then()
  • reject:拒绝状态,当主动回调reject时,就处于该状态,并且回调 .catch()

Promise的另外处理形式:

不使用.catch(),在 .then() 中,使用两个函数,第一个为resolve回调,第二个为reject回调

Promise的链式调用

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

需求:

  • 网络请求: aaa -> 自己处理(10行)
  • 处理:aaa111 -> 自己处理(10行)

  • 处理:aaa111222 -> 自己处理

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

new Promise(resolve => resolve(结果))简写

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

省略掉Promise.resolve

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

在进行第一层处理后,返回错误

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("aaa");
  }, 1000);
})
  .then((res) => {
    // 1.自己处理10行代码
    console.log(res, "第一层处理的10行代码");
    // 2.对结果进行第一次处理
    // 方法一:
    // return Promise.reject("error");
    // 方法二:
    throw "error";
  })
  .then((res) => {
    console.log(res, "第二层处理的10行代码");
    return Promise.resolve(res + "222");
  })
  .then((res) => {
    console.log(res, "第三层处理的10行代码");
  })
  .catch((err) => {
    console.log(err);
  });

Promise的all方法使用

当某个需求需要两个请求都完成后执行回调函数

传统ajax方法:

使用Promise.all方法

使用定时器模拟

Promise.all([
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ name: "xiaoming", age: 18 });
    }, 2000);
  }),
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ name: "xiaohong", age: 16 });
    }, 1000);
  }),
]).then((results) => {
  console.log(results);
});

最终结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值