写点什么

【Promise 源码学习】第二篇 - Promise 功能介绍与特性分析

作者:Brave
  • 2021 年 11 月 09 日
  • 本文字数:3212 字

    阅读完需:约 11 分钟

一,前言


上一篇,对 Promise 进行了简单介绍,主要涉及以下几个点:


  • Promise 简介和基本使用;

  • Promise 和 callback 对比;

  • Promise 的重要性和作用;

  • Promise 使用场景:Promisify 封装;

  • Promise 的优缺点、兼容性;


本篇,将结合示例对 Promise 进行相关功能介绍与特性分析;


备注:

  • 本篇持续更新,争取覆盖 Promise 大多数基础功能和特性;

  • 较为复杂的面试题部分,会在专栏最后集中进行梳理和总结;


二,Promise 基础特性

1,Promise 类


  • Promise 能够通过 new 进行对象创建,说明它是一个类或或构造函数;

  • 使用 Promise 时,需要传入一个 executor 执行器;

  • executor 执行器的入参包含 reslove 和 reject 两个函数;


  • 引出了 executor 执行器;

  • 引出了 reslove 和 reject;

2,executor 执行器


代码示例:

new Promise(()=>{ // executor 执行器  console.log('promise')})console.log('ok')
// 执行结果:promiseok
复制代码


  • 现象:先输出 promise,后输出 ok;

  • 所以,executor 执行器会在 Promise 创建完成后被立即执行


  • 介绍了 executor 执行器;会在 Promise 创建后被立即执行;

3,Promise 的三种状态


Promise 具有三种状态:

  • pending:等待态(默认);

  • fulfilled:成功态;

  • rejected:失败态;


代码示例:

let promise = new Promise(()=>{  console.log('promise')})console.log('ok', promise)
// 执行结果:promiseok Promise { <pending> }
复制代码


  • Promise 状态默认为 pending 等待态:

  • Promise 状态可以通过调用 reslove 或 reject 改变(仅能够被改变一次);


  • 介绍了 Promise 的三种状态;

  • 引出了 reslove、reject 与 Promise 状态的关系;

4,reslove 和 reject 的作用


executor 执行器的两个函数 reslove 和 reject,用于描述 Promise 状态:

  • 当异步操作成功时,通过调用 resolve 返回异步操作的成功结果;

  • 当异步操作失败时,通过调用 reject 返回异步操作的失败结果;


reslove

  • 通过调用 reslove 函数,使当前 Promise 状态变更为成功态 fulfilled;

  • resolve 表示成功,可以传入一个 value;


示例:

let promise = new Promise((resolve, reject)=>{  console.log('promise')  resolve("成功");  // 调用 resolve 方法})console.log('ok', promise)
// 执行结果:promiseok Promise { '成功' }
复制代码


reject

  • 通过调用 reject 函数,使当前 Promise 状态变更为失败态 rejected;

  • reject 表示失败,可以传入一个 reason;


实例:

let promise = new Promise((resolve, reject)=>{  console.log('promise')  reject("失败");  // 调用 reject 方法})console.log('ok', promise)
// 执行结果:promiseok Promise { <rejected> '失败' }
复制代码


  • 介绍了 reslove 和 reject 的使用方式:调用和传参;

  • 介绍了 reslove、reject 与 Promise 状态的对应关系;

5,Promise 实例的状态只能改变一次


代码示例:

let promise = new Promise((resolve, reject)=>{  console.log('promise')  throw new Error("抛出错误");  resolve();  // 已经失败了,再调用resolve成功,状态不会发生变化})promise.then((value)=>{  console.log('success', value) },(reson)=>{  console.log('err',reson)})console.log('ok')
// 执行结果:promiseokerr Error: 抛出错误
复制代码


Promise 实例的状态一旦发生变化,不能再次被更改:

  • promise 状态只能从 pending 更新为 fulfilled 成功态,或是从 pending 更新为 rejected 失败态;

  • 当 promise 为成功或失败状态时,不能再次通过调用 resolve、reject 或抛出异常来改变 当前 promise 实例的状态;


示例中使用到了 promise.then() ,将会在下边进行详细介绍;

6,Promise API


与绝大多数的“class 类”相似,Promise API 也分为以下两大类:

  • 实例 API 或原型方法:必须要 new 出实例才能使用的实例方法;

  • 静态 API 或类方法:不需要 new 出实例就可以使用的静态方法;


其中,分别包含了以下方法:

  • Promise 共有 3 个实例方法:thencatchfinally

  • Promise 共有 4 个静态方法:resolverejectallrace


三,Promise 实例 API(原型方法)


Promise 共有 4 个实例方法,分别是:thencatchfinally

1,Promise.prototype.then()

功能介绍


  • 每个 Promise 实例都有一个 then 方法;

  • Promise 对异步操作执行结果的处理:

  • 通过调用 resolve 使状态更新为成功态,进入 then 成功回调处理;

  • 通过调用 reject 使状态更新为失败态,进入 then 失败回调处理;

  • then 方法的两个参数(onFulfilled 和 onRejected):

  • 第一个参数:onFulfilled 成功的回调:成功状态时被调用;

  • 第二个参数:onRejected 失败的回调:失败状态时被调用;

代码示例

// promise 有三种状态:成功态,失败态,等待态(默认)// 调用 resolve,状态更新为成功态,进入 then 成功回调;// 调用 reject,状态更新为失败态,进入 then 失败回调;// 每个 promise 实例的状态只能给改变一次;let promise = new Promise((resolve, reject)=>{  console.log('promise')  resolve("成功");     // 进入 then 成功处理  // reject("失败");   // 进入 then 失败处理  // throw new Error("发生错误"); // 进入 then 失败处理})
promise.then((value)=>{ console.log('success', value) // onFulfilled:成功状态时被调用},()=>{ console.log('err') // onRejected:失败状态时被调用 })
console.log('ok')
// 执行结果:promise -> executor 被立即执行ok -> 直接执行完毕,then 方法为异步success 成功 -> promise 异步处理完成,进入 then 中 onFulfilled 函数
复制代码


  • 从控制台输出可以看出:promise 实例创建后 executor 被立即执行,但是 then 方法却是异步执行的;


备注:

  • 调用 resolve 会进入成功处理;

  • 调用 reject 或发生异常会进入失败处理;

  • 若在 Promise 中既没有调用 resolve 也没有调用 reject,此时的 Promise 默认为等待态;将不会进入成功或失败的回调,即不会进入 then 方法处理;

进入条件

Promise 主体任务此前链式调用中的全部回调任务都成功时(即通过 resolve 标注状态),进入本次 then() 回调;

2,Promise.prototype.catch()

功能介绍


Promise.prototype.catch()方法就是 .then(null, rejection).then(undefined, rejection)的别名, 用于指定发生错误时的回调函数;

代码示例

进入条件

Promise 主体任务此前链式调用中出现异常且未被捕获时(即通过 reject 标注状态或出现 JS 原生报错且没有被处理时),进入本次 catch()回调;

3,Promise.prototype.finally()

功能介绍

代码示例

进入条件


无论链式调用过程中是否出现成功或者失败,最终都将会执行 finally 方法,除非没有添加 .finally 处理;

四,Promise 静态 API(类方法)


Promise 共有 4 个静态方法,分别是:resolverejectallrace

1,Promise.resolve()

功能介绍

  • Promise.resolve():创建并返回一个成功状态的 Promise 实例;

  • 常用于构建微任务;(构建宏任务常用setTimeout);

代码示例

以下示例并没问题,但却是一个冗余的 Promise 封装:


// 冗余的 Promise 封装function getData() {  return new Promise((resolve) => {    const a = 1;    const b = 2;    const c = a + b;    resolve(c);  })}
复制代码


这种情况,可以直接使用 Promise.resolve 快速创建一个成功状态的 Promise 对象,构建成为一个微任务:

function getData() {  const a = 1;  const b = 2;  const c = a + b;  return Promise.resolve(c); // 创建成功状态 promise 实例,放入微任务队列}
复制代码

2,Promise.reject()

功能介绍

  • Promise.reject():创建并返回一个失败状态的 Promise 实例;

代码示例

3,Promise.all()

功能介绍

代码示例

4,Promise.race()

功能介绍

代码示例


五,结尾


本篇,主要通过示例对 Promise 进行了相关功能的介绍与特性分析;

下一篇,介绍 Promise A+ 规范,后续会从 0 ~ 1 实现一个 Promise;


维护日志

  • 20211025

  • 重新梳理文章大纲,整理目录,扩充相关内容;

  • 更新文章摘要;

  • 20211103

  • 修改错别字;

用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Promise 源码学习】第二篇 - Promise 功能介绍与特性分析