飞道的博客

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

375人阅读  评论(0)

一,前言

上一篇,对 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')

// 执行结果:
promise
ok
  • 现象:先输出 promise,后输出 ok;
  • 所以,executor 执行器会在 Promise 创建完成后被立即执行
  • 介绍了 executor 执行器;会在 Promise 创建后被立即执行;

3,Promise 的三种状态

Promise 具有三种状态:

  • pending:等待态(默认);
  • fulfilled:成功态;
  • rejected:失败态;

代码示例:

let promise = new Promise(()=>{
   
  console.log('promise')
})
console.log('ok', promise)

// 执行结果:
promise
ok 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)

// 执行结果:
promise
ok Promise {
    '成功' }

reject

  • 通过调用 reject 函数,使当前 Promise 状态变更为失败态 rejected;
  • reject 表示失败,可以传入一个 reason;

实例:

let promise = new Promise((resolve, reject)=>{
   
  console.log('promise')
  reject("失败");	// 调用 reject 方法
})
console.log('ok', promise)

// 执行结果:
promise
ok 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')

// 执行结果:
promise
ok
err 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 的基础特性;
  • Promise 实例 API(原型方法)的介绍和使用;
  • Promise 静态 API(类方法)的介绍和使用;

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


维护日志

  • 20211025
    • 重新梳理文章大纲,整理目录,扩充相关内容;
    • 更新文章摘要;
  • 20211103
    • 修改错别字;
  • 20211120
    • 修改结尾部分,修改文章摘要;

转载:https://blog.csdn.net/ABAP_Brave/article/details/128764677
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场