写点什么

【Promise 源码学习】第三篇 - 实现一个简版 Promise

作者:Brave
  • 2021 年 11 月 10 日
  • 本文字数:2374 字

    阅读完需:约 8 分钟

一,前言


上一篇,结合示例介绍了 Promise 相关功能与特性分析,包含以下内容:


  • Promise 基础特性;

  • Promise 实例 API(原型方法);

  • Promise 静态 API(类方法);

  • Promsie 在不同场景下的特性分析;


本篇,根据之前对 Promise 的分析和了解,实现一个简版 Promise;


二,Promise 的实现思路


基于前面对 Promise 使用上的了解和分析,Promise 有以下几个关键特征:


  • Promise 是一个类;

  • 构造函数接收的参数是一个 excutor 函数;

  • 这个函数的参数是 resolve 和 reject 两个内部函数;

  • 构建 resolve 和 reject 并传入 excutor,并使之立即执行;

  • Promise 类有三种状态,默认为等待态;

  • 在 resolve 和 reject 中修改 status 状态;

  • Promise 类中包含 then 和 catch 等方法;


那么,一个 Promise 的结构如下:

class Promise () {  constructor (fun) {    this.status = 'pending'; // status:pending、fulfilled、rejected    fun(this.resolve, this.reject); // 主体函数将会被立即执行  }  resolve() {}  reject() {}  then() {}  catch() {}}
复制代码



三,Promise A+ 规范(简版)


上边的代码是根据理解“猜测”出来的,比较严谨的应该根据 Promise A+ 规范进行实现;


备注:本篇仅介绍 Promise A+ 规范中的基础部分,用于支撑实现简版 Promise;

1,技术点



  • 1.1 promise 是一个对象或函数,要有一个 then 方法,而且 then 方法需要符合规范;

  • 1.2 thenable 是一个对象或函数

  • 1.3 value 是一个合法的 js 值,可以是 undefined,一个 thenable 对象,或者是一个 promise 对象;

  • 1.4 异常可以使用 throw 代码块抛出

  • 1.5 reson 是一个值,它告诉我们 promise 为什么被拒绝了


简单分析:

  • promise 有多种实现方式,可以是对象也可以是函数;符合标准即可;

  • 由于 promise 实例可以.then,所以我们认为 promise 实例是一个 thenable 对象;

  • 调用 reslove() 可以传值,不传就是 undefined,也可以传入 promise 或 thenable;

2,必要的


2.1 promise 状态



promise 有三个状态:pending 等待态, fulfilled 成功态 和 rejected 失败态.


  • 2.1.1 当 promise 为 pending 等待态 时,可以转换为 fulfilled 成功态 或 rejected 失败态.

  • 2.1.2 当 promise 为 fulfilled 成功态 时

  • 2.1.2.1 不能被转化为其他状态

  • 2.1.2.2 必须有一个值,且不能被改变

  • 2.1.3 当 promise 为 rejected 失败态 时

  • 2.1.3.1 不能被转化为其他状态

  • 2.1.3.2 必须有一个原因,且不能被改变


2.2 then 是一个方法



一个 promise 必须有一个 then 方法,而且能够访问成功或失败的值;一个 promise 能够接收两个参数,onFulfilled 和 onRejected;


。。。后面的内容暂时略过。。。


备注:了解至以上内容,足以支撑实现简版 Promise;


那么,可以基于以下 5 点,实现一个简版的 Promise:

1,promise 是一个类;2, 使用 promise 时,传入 executor 执行器,并被立即执行;3,executor 参数是两个函数,用于描述 promise 实例的状态;resolve 表示成功,可以传入一个 value;reject 表示失败,可以传入一个 reason;4,每个 Promise 实例都有一个 then 方法;5,promise 一旦状态发生后,不能再更改,promise 有三种状态:成功态,失败态,等待态(默认)
复制代码



四、实现简版 Promise

// 声明 promise 三种状态const PENDING = 'PENDING';     // 等待态const DULFILLED = 'DULFILLED'; // 成功态const REJECTED = 'REJECTED';   // 失败态
class Promise{ // 通过 new Promise 进行实例化时,传入 executor 执行器函数 constructor(executor){
this.value = undefined; // 保存成功的原因,then中调用onFulfilled时传入 this.reason = undefined; // 保存失败的原因,then中调用onFulfilled时传入 this.state = PENDING; // promise 状态,默认等待态 // 成功 reslove 函数、失败reject函数,并传入executor const reslove = (value) =>{ // 等待态 --> 成功态 if(this.state === PENDING){ this.value = value this.state = DULFILLED; } } const reject = (reason) =>{ // 等待态 --> 失败态 if(this.state === PENDING){ this.reason = reason this.state = REJECTED; } } // 立即执行 executor 执行器函数,通过 try...catch... 进行异常捕捉; try{ executor(reslove, reject); }catch(e){ reject(e) // 有异常,调用 reject 更新为失败态 } } // 定义 then 方法:包含两个参数 onFulfilled 和 onRejected; // 根据 Promise 状态,执行 onFulfilled 或 onRejected; then(onFulfilled, onRejected){ // 成功态,调用 onFulfilled,传入成功 value if(this.state === DULFILLED){ onFulfilled(this.value) } // 失败态,执行 onRejected,传入失败 reason if(this.state === REJECTED){ onRejected(this.reason) } }}
// 导出 Promise 类供外部使用module.exports = Promise;
复制代码


测试 promise 基础功能:

// 1,引入简版 Promiselet Promise = require('./source/promise');  
// 2.实例化 Promise 并传入 executor 执行器函数(会立即被执行)let promise = new Promise((resolve, reject)=>{ console.log('promise') throw new Error("抛出错误");})
// 3,then 方法promise.then((value)=>{ console.log('success', value) },(reason)=>{ console.log('err', reason)})console.log('ok')
// 执行结果promiseerr Error: 抛出错误
复制代码


这样,就完成了一个简版(示意版本)的 Promise;


五,结尾


本篇,根据对 Promise 的分析和了解,实现了一个简版 Promise,主要涉及以下内容:


  • Promise 的实现思路;

  • Promise A+ 规范(简版);

  • Promise 简版实现和功能测试;


下一篇,翻译并理解 Promise A+ 规范;

用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Promise 源码学习】第三篇 - 实现一个简版 Promise