使用promise报错_Promise实现原理解析

本文深入探讨Promise的实现原理,包括状态机、转换器、构造器和观察者模式。详细解释了如何通过then、catch、finally和扩展API如Promise.resolve、Promise.reject、Promise.all及Promise.race来处理异步操作。文章旨在帮助读者深化对Promise的理解和使用。
摘要由CSDN通过智能技术生成

7380b5bb204faf1be9361c6668f6746e.png

前言

大家平时基本上都听过或者用过Promise,大部分基本都是拿来主义(当然也包括我),而对于原理知之甚少,这样不利于日后问题的排查和代码的优化。为此,我写这篇文章来加深对Promise的理解和使用。本文假设读者都是对Promise的使用有一定了解的基础上展开的,因此没对Promise的基本使用做过多的介绍。然后,我将通过以下几个部分来讲解:

  • 基本实现
  • 扩展功能实现
  • 扩展API实现

基本实现

State Machine(状态机)

a5c1670427f08e5f12f91eb0325e70e5.png

Promise本质上其实是一个状态机,由PENDINGFULFILLEDREJECTED 这个三个状态组成,初始状态为PENDING。因此,我们创建一个简单的状态机,state为当前的状态,value为结果值,deferrals为延迟处理的任务(当Promise状态处于PENDING时添加的任务),deferralsState为延迟任务的数量(0表示没有延迟任务,1表示一个延迟任务,2表示两个及以上延迟任务)。

var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise() {
    
  this.state = PENDING;
  this.value = null;
  this.deferralsState = 0;
  this.deferrals = null;
}

Transitions(转换器)

根据规定,Promise状态的改变是有限制的,即只能PENDING->FULFILLEDPENDING->REJECTED,而且这种改变是不可逆的。除此之外,当处于FULFILLED状态下,Promise必须要一个value,而且这个value是不可改变的;当处于REJECTED状态下,Promise必须要有一个reason(报错),而且这个reason也是不可改变的。

我们创建resolvereject来表示Promise状态的改变并把调用者传递过来的值赋给value。可是调用者可能传各种类型的值过来,如果传Promise进来,我们是无法直接取值的,那么我们就通过then函数(后面会介绍)来取值,并通过递归调用doResolve函数(后面会介绍)来把参数Promise中的value传递到我们当前Promise中,而递归调用的目的是为了防止多重嵌套情况的发生。那finale的作用是什么呢?之前我们说过,当Promise还处于PENDING状态的时候,我们会把添加的待办任务放入deferrals中,在状态改为FULFILLEDREJECTED后,我们统一处理。

function resolve(self, newValue) {
    
  if (
    newValue &&
    (typeof newValue === "object" || typeof newValue === "function")
  ) {
    
    var then = getThen(newValue);
    if (then === IS_ERROR) {
    
      return reject(self, LAST_ERROR);
    }
    if (typeof then === "function") {
    
      doResolve(then.bind(newValue), self);
      return;
    }
  }
  self.state = FULFILLED;
  self.value = newValue;
  finale(self);
}

function reject(self, newValue) {
    
  self.state = REJECTED;
  self.value = newValue;
  finale(self);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值