js【详解】Promise(含 Promise 的三种状态及其变化,创建 Promise, Promise.all 语法、Promise.all 实战范例、手写 Promise.all)

简介: js【详解】Promise(含 Promise 的三种状态及其变化,创建 Promise, Promise.all 语法、Promise.all 实战范例、手写 Promise.all)

为什么需要使用 Promise ?

传统回调函数的代码层层嵌套,形成回调地狱,难以阅读和维护,为了解决回调地狱的问题,更加优雅地书写复杂的异步任务,诞生了 Promise

什么是 Promise ?

Promise 是一种异步编程的解决方案,本身是一个构造函数

console.log(Promise); // [Function: Promise]

自带resolve,reject,all 等方法,其原型上还有then、catch等方法。

Promise 的三种状态及其变化

  1. pending 进行中,不会触发 then 和 catch 回调函数
  2. resolved / fulfilled 已成功,会触发后续的 then 回调函数
  3. rejected 已失败,会触发后续的 catch 回调函数


Promise 的状态变化如上图所示,不可逆

  • Promise 最初的状态是 pending
  • pending 状态的 Promise 执行 resolve() 后,状态变为 resolved
Promise.resolve(); // Promise 的状态从 pending 变为 resolved

resolved 状态的 Promise 会触发后续的 then 函数,

  • 若 then 函数内没有报错,则返回一个 resolved 状态的 Promise
Promise.resolve().then(() => {}); // 最终 Promise 的状态为 resolved

若 then 函数内报错,则返回一个 rejected 状态的 Promise

Promise.resolve().then(() => {
  throw new Error("then函数出现报错");
}); // 最终 Promise 的状态为 rejected

pending 状态的 Promise 执行 reject() 后,状态变为 rejected

Promise.reject(); // Promise 的状态从 pending 变为 rejected

rejected 状态的 Promise 会触发后续的 catch 函数,

  • 若 catch 函数内没有报错,则返回一个 resolved 状态的 Promise
Promise.reject().catch(() => {}); // 最终 Promise 的状态为 resolved

若 catch 函数内报错,则返回一个 rejected 状态的 Promise

Promise.reject().catch(() => {
  throw new Error("catch函数出现报错");
}); // 最终 Promise 的状态为 rejected

创建 Promise

新创建的 Promise 实例的状态为 pending

// 此时,p1 的状态为 pending
const p1 = new Promise((resolve, reject)=>{
 
})

执行 resolve() ,Promise 实例的状态变为 fulfilled

const p1 = new Promise((resolve, reject) => {
  resolve()
})

执行 reject() ,Promise 实例的状态变为 reject

const p1 = new Promise((resolve, reject) => {
  reject()
})

Promise.all

Promise .all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);
  • p1、p2、p3 都是 Promise 实例,得到的 p 也是Promise 实例
  • Promise .all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
  • p1、p2、p3 的状态都变成 fulfilled, p 的状态才会变成 fulfilled
  • p1、p2、p3 之中有一个被 rejected,p 的状态就变成 rejected
  • p 的 then 函数中得到的是 p1、p2、p3 的返回值组成的一个数组

promise.all 实战范例

import axios from 'axios'

let infoList = []

let id_list = ['1', '2', '3']

let promise_list = []

for (let id of id_list) {
  promise_list.push(axios.get(`http://jsonplaceholder.typicode.com/users/${id}`))
}

Promise.all(promise_list).then((res) => {
  infoList = res.map((item) => item.data)
  console.log(infoList) // 得到预期结果
})

手写 promise.all

function pAll (_promises) {
    return new Promise((resolve, reject) => {
      // Iterable => Array
      const promises = Array.from(_promises)
      // 结果用一个数组维护
      const r = []
      const len = promises.length
      let count = 0
      for (let i = 0; i < len; i++) {
        // Promise.resolve 确保把所有数据都转化为 Promise
        Promise.resolve(promises[i]).then(o => { 
          // 因为 promise 是异步的,保持数组一一对应
          r[i] = o;
  
          // 如果数组中所有 promise 都完成,则返回结果数组
          if (++count === len) {
            resolve(r)
          }
          // 当发生异常时,直接 reject
        }).catch(e => reject(e))
      }
    })
 }

Promise 自测题

此时仅创建了 Promise 对象,没有执行 resolve() 或 reject(),所以状态是 pending

因 setTimeout 是异步任务,内部代码在打印完 p2 后才执行,所以在打印 p2 时,Promise 还没执行 resolve() ,状态是 pending。

打印完 p2 后,setTimeout 内的 resolve() 执行,Promise 的状态变为 resolved

目录
相关文章
|
5天前
|
存储 前端开发 JavaScript
Next.js 实战 (一):项目搭建指南
这篇文章介绍了作者在2024年下半年计划使用Next.js从零开始搭建一个后台模板,以探索Next.js的奥秘。文章包含了项目搭建、目录结构、APP路由约定、配置Eslint、Prettierrc、Husky等项目提交规范、使用release-it自动管理版本号和生成CHANGELOG、import排序规则、安装NextUI等内容。作者还提到会在开发过程中记录遇到的问题和解决方法,并计划在后期使用Prisma+Supabase数据库存储数据,最终完成一个基于Next.js的全栈项目。
Next.js 实战 (一):项目搭建指南
|
2天前
|
JavaScript
JS【实战】跨域的网页链接跳转
JS【实战】跨域的网页链接跳转
4 0
|
3天前
|
前端开发 JavaScript
js 打开资源管理器(经典范例:纯前端选择并预览图片)
js 打开资源管理器(经典范例:纯前端选择并预览图片)
15 0
|
4天前
【wavesurfer.js实战范例】多区域音频标注(含区域实时切换显示)
【wavesurfer.js实战范例】多区域音频标注(含区域实时切换显示)
13 0
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的个人健康管理系统小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的个人健康管理系统小程序附带文章源码部署视频讲解等
11 2
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的高校宿舍信息管理系统小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的高校宿舍信息管理系统小程序附带文章源码部署视频讲解等
8 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的电影交流平台小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的电影交流平台小程序附带文章源码部署视频讲解等
12 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的电器维修系统小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的电器维修系统小程序附带文章源码部署视频讲解等
8 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的大学生校园兼职微信小程序附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的大学生校园兼职微信小程序附带文章源码部署视频讲解等
12 1
|
2天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的二手物品交易平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的二手物品交易平台附带文章源码部署视频讲解等
10 1