首页 > 其他分享 >第十三篇 手写原理代码 - 实现 Promise

第十三篇 手写原理代码 - 实现 Promise

时间:2023-04-12 12:11:08浏览次数:32  
标签:resolve fulfilled reason Promise result reject 十三篇 手写

当使用 JavaScript 进行异步编程时,我们往往需要面对回调地狱(callback hell)、代码可读性低、错误处理困难等问题。为了解决这些问题,ECMAScript 6(ES6)中引入了 Promise。

Promise 是一种用于处理异步操作的对象,它是一个容器,保存着未来才会结束的事件(通常是一个异步操作),并提供了一组标准化的方法,允许开发者以同步的方式处理异步操作的结果。Promise 可以更好地组织和管理异步代码,使其更易于阅读和维护。

Promise 的最基本的概念就是将一个异步操作封装成一个 Promise 对象,该对象代表了这个异步操作在未来的某个时刻会返回一个值或者抛出一个错误。Promise 对象有三个状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。当 Promise 对象处于 pending 状态时,可以继续等待异步操作完成,当异步操作成功完成时,Promise 对象进入 fulfilled 状态,并返回执行结果;当异步操作失败时,Promise 对象进入 rejected 状态,并返回错误信息。

使用 Promise 对象时,我们可以通过调用 then 方法来注册成功回调函数,调用 catch 方法来注册错误回调函数。如果 Promise 对象已经处于 fulfilled 或者 rejected 状态,那么回调函数会立即被执行;否则,回调函数会在 Promise 对象的状态改变后被执行

一个 Promise 对象有三个状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。同时还具有 then 方法,用于将 fulfilled 和 rejected 状态的结果返回给调用者

实现 Promise

class MyPromise {
  constructor(executor) {
    // 初始化状态为 pending
    this.status = 'pending';
    // 保存 fulfilled 和 rejected 的结果
    this.value = null;
    this.reason = null;
    // 存储 fulfilled 和 rejected 的回调函数
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    // 执行 executor 函数
    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (err) {
      this.reject(err);
    }
  }

  // 定义 resolve 和 reject 函数
  resolve(value) {
    if (this.status === 'pending') {
      this.status = 'fulfilled';
      this.value = value;
      // 执行所有的 fulfilled 回调函数
      this.onFulfilledCallbacks.forEach((callback) => callback(this.value));
    }
  }

  reject(reason) {
    if (this.status === 'pending') {
      this.status = 'rejected';
      this.reason = reason;
      // 执行所有的 rejected 回调函数
      this.onRejectedCallbacks.forEach((callback) => callback(this.reason));
    }
  }

  // 定义 then 方法
  then(onFulfilled, onRejected) {
    // 如果 onFulfilled 不是函数,就将其设置为默认回调函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
    // 如果 onRejected 不是函数,就将其设置为默认回调函数
    onRejected =
      typeof onRejected === 'function'
        ? onRejected
        : (reason) => {
            throw reason;
          };

    // 存储回调函数
    if (this.status === 'pending') {
      this.onFulfilledCallbacks.push(onFulfilled);
      this.onRejectedCallbacks.push(onRejected);
    } else if (this.status === 'fulfilled') {
      onFulfilled(this.value);
    } else {
      onRejected(this.reason);
    }

    // 返回新的 Promise 对象
    return new MyPromise((resolve, reject) => {
      if (this.status === 'pending') {
        this.onFulfilledCallbacks.push(() => {
          try {
            const result = onFulfilled(this.value);
            this.resolvePromise(result, resolve, reject);
          } catch (err) {
            reject(err);
          }
        });

        this.onRejectedCallbacks.push(() => {
          try {
            const result = onRejected(this.reason);
            this.resolvePromise(result, resolve, reject);
          } catch (err) {
            reject(err);
          }
        });
      } else if (this.status === 'fulfilled') {
        try {
          const result = onFulfilled(this.value);
          this.resolvePromise(result, resolve, reject);
        } catch (err) {
          reject(err);
        }
      } else {
        try {
          const result = onRejected(this.reason);
          this.resolvePromise(result, resolve, reject);
        } catch (err) {
          reject(err);
        }
      }
    });
  }

  // 解析 then 方法返回的值,如果是 Promise 对象就进行递归解析
  resolvePromise(result, resolve, reject) {
    if (result instanceof MyPromise) {
      result.then(resolve, reject);
    } else {
      resolve(result);
    }
  }
}

标签:resolve,fulfilled,reason,Promise,result,reject,十三篇,手写
From: https://www.cnblogs.com/caix-1987/p/17309378.html

相关文章

  • 第十一篇 手写原理代码 - 实现事件订阅中类
    javaScript中的订阅发布模式(也称为观察者模式)是一种设计模式,用于在对象之间的事件通信中。该模式由两部分构成:发布者和订阅者。发布者持有所有订阅者的引用,在某个事件发生时通知所有的订阅者,从而触发它们的相应行为。这种模式可以用于解耦发布者和订阅者之间的依赖关系,从而实......
  • 手写防抖节流函数
    防抖函数functiondebounce(fn,t){  lettimeId  returnfunction(){//如果有定时器就清除  if(timeId)clearTimeout(timeId)//开启定时器200  timeId=setTimeout(function(){   fn()  },t) }}//节流函数throttlefunctionth......
  • 手写一个深拷贝
    functiondeepClone(obj){if(typeofobj!='object')returnobject//1、建立新容器vartemp=array.isArray(obj)?[]:{}//2、通过遍历将原有数组的值循环出来放到新建立的容器上for(letkeyinobj){if(obj.hasOwnProper......
  • 第二篇 手写原理代码 - 函数【 函数防抖 、函数节流 】
    函数防抖和函数节流都是优化高频事件处理的JavaScript技术。它们可以限制函数的调用,在一定程度上减少计算、网络请求和提高响应速度,但它们的实现方式略有不同函数防抖:延迟执行函数,只有在事件停止后才会执行最后一次事件函数节流:定期执行函数,每隔一段时间执行一次通常情况下,......
  • 第四篇 手写原理代码 - 函数 【 实现 compose 函数 】
    JavaScript中的Compose函数用于组合一些函数,使得每个函数都接收上一个函数的返回值作为参数,并返回一个新的函数。可以使用这种方式把多个函数串起来,从而实现更复杂的逻辑Comopse函数是一个非常有用的工具,它可以帮助我们简化程序逻辑,实现代码复用,提高开发效率实现compose......
  • 第六篇 手写原理代码 - 对象 【 实现 AJAX 请求 】
    AJAX是AsynchronousJavaScriptandXML的缩写,指的是通过JavaScript和XML技术在不重新加载整个页面的情况下,实现与服务器之间异步通信的技术。使用AJAX技术能够使网页更加动态和用户友好。JavaScript的AJAX技术借助于浏览器内置的XMLHttpRequest对象实现。XMLHttp......
  • 第五篇 手写原理代码 - 对象 【 实现 new 过程、实现 instanceof 】
    在JavaScript中,new关键字用于创建一个对象实例,它通常与构造函数一起使用。当使用new关键字时,会发生以下几件事情:1、创建一个新对象,并将该对象的属性设置为构造函数的原型(即__proto__)2、将构造函数的作用域绑定到新对象上,并执行构造函数中的代码3、如果构造函数返......
  • 第七篇 手写原理代码 - 对象 【 实现对象的深度拷贝、实现对象的深度对比 】
    在JavaScript中,对象拷贝可以分为浅拷贝和深拷贝两种方式1、浅拷贝浅拷贝只是复制了对象的引用地址,新对象的属性与原对象的属性指向同一块内存地址2、深拷贝深拷贝会完整地复制对象以及其内部所有嵌套对象使用JSON.parse(JSON.stringify())方法进行深拷贝......
  • 第九篇 手写原理代码 - 数组 【 实现 forEach、map、filter、every、some 】
    1、forEachArray.prototype.my_forEach=function(callback){for(leti=0;i<this.length;i++){callback(this[i],i,this);}};2、mapArray.prototype.my_map=function(callback){constarr=[];for(leti=0;i<this.length;......
  • 第八篇 手写原理代码 - 对象 【 实现 Object.assign() 和 Object.create() 】
    1、Object.assign(target,...sources)Object.assign()方法用于将一个或多个源对象的属性复制到目标对象中。它只复制源对象自身可枚举的属性,同时也能够拷贝getter和setter函数2、Object.create(proto[,propertiesObject])Object.create()方法创建一个新对象,使......