首页 > 其他分享 >手写Promise

手写Promise

时间:2024-08-17 19:48:37浏览次数:4  
标签:resolve return .# value callBack Promise reject 手写

  实现功能如下:

  1. Promise构造函数
  2. promise实例then方法
  3. pomise实例catch方法
  4. promise实例finally方法
  5. Promise静态resolve方法
  6. Promise静态reject方法
  7. Promise静态all方法
    备注:参照渡一教育视频
    代码:
      1 const Pending = 'pending';
      2 const FullFiled = 'fulfilled';
      3 const Rejected = 'rejected';
      4 class MyPromise {
      5     #status = Pending;
      6     #value = '';
      7     #taskList = [];
      8     constructor(executor) {
      9         try {
     10             executor(this.#resolve, this.#reject);
     11         } catch (error) {
     12             this.#reject(error);
     13         }
     14 
     15     }
     16     #resolve = (data) => {
     17         this.#changeState(FullFiled, data);
     18     }
     19 
     20     #reject = (reason) => {
     21         this.#changeState(Rejected, reason);
     22     }
     23 
     24     #changeState = (status, value) => {
     25         if (status === Pending) return;
     26         this.#status = status;
     27         this.#value = value;
     28         this.#eventLoop();
     29     }
     30 
     31     // 判断then中的返回值是否复合PromiseA+规范
     32     #isPromiseA = (callBack) => {
     33         if (callBack !== null && (typeof callBack === 'object' || typeof callBack === 'array')) {
     34             return typeof callBack.then === 'function';
     35         }
     36         return false;
     37     }
     38 
     39     // 手动将promise.then中的函数放入微队列中
     40     // nodeJS环境使用process.nextTick()
     41     // 浏览器环境使用MutationObserver()
     42     #addMicroTaskList = (callBack) => {
     43         if (typeof process === 'object' && typeof process.nextTick === 'function') {
     44             process.nextTick(callBack);
     45             return;
     46         }
     47         if (typeof MutationObserver === 'function') {
     48             let m = new MutationObserver(callBack);
     49             let div = document.createElement("div");
     50             m.observe(div, {
     51                 childList: true
     52             });
     53             div.innerText = "1";
     54             return;
     55         }
     56         // 其他环境
     57         setTimeout(callBack, 0);
     58     }
     59 
     60     // promise.then中的函数需要放到微队列执行,
     61     // then中的参数有三种情况
     62     // 1. 参数不是函数,promise穿透到下一个then
     63     // 2. 参数是一个函数,
     64     // 2.1 函数的返回值不是promise,直接resolve(this.value)
     65     // 2.2 函数的返回值是promise, 调用promise.then()
     66     #handelOneTask = (callBack, resolve, reject) => {
     67         this.#addMicroTaskList(() => {
     68             if (typeof callBack === 'function') {
     69                 try {
     70                     const result = callBack(this.#value);
     71                     if (this.#isPromiseA(result)) {
     72                         result.then(resolve, reject);
     73                     } else {
     74                         resolve(result);
     75                     }
     76                 } catch (error) {
     77                     reject(error);
     78                 }
     79 
     80             } else {
     81                 // 如果then中的两个参数不是函数,则promise穿透到下一层then
     82                 if (this.#status === FullFiled) {
     83                     resolve(this.#value);
     84                 } else if (this.#status === Rejected) {
     85                     reject(this.#value);
     86                 }
     87             }
     88         });
     89     }
     90 
     91     // 每次调用then方法和promise的状态发生改变时,执行then中的回调函数
     92     #eventLoop = () => {
     93         if (this.#status === Pending) return;
     94         while (this.#taskList.length) {
     95             const { successCal, errorCal, resolve, reject } = this.#taskList.shift();
     96             switch (this.#status) {
     97                 case FullFiled:
     98                     this.#handelOneTask(successCal, resolve, reject);
     99                     break;
    100                 case Rejected:
    101                     this.#handelOneTask(errorCal, resolve, reject);
    102                     break;
    103                 default:
    104                     break;
    105             }
    106 
    107         }
    108     }
    109 
    110     // then方法接收resolve和reject的回调函数
    111     then = (successCal, errorCal) => {
    112         return new MyPromise((resolve, reject) => {
    113             this.#taskList.push({ successCal, errorCal, resolve, reject });
    114             this.#eventLoop();
    115         })
    116     }
    117 
    118     catch = (callBack) => {
    119         return this.then(undefined, callBack);
    120     }
    121 
    122     finally = (callBack) => {
    123         return this.then((data) => {
    124             callBack();
    125             return data;
    126         }, (err) => {
    127             callBack();
    128             throw err;
    129         })
    130     }
    131 
    132     static resolve = (value) => {
    133         if (value instanceof MyPromise) return value;
    134         let _resolve, _reject;
    135         const p = new MyPromise((resolve, reject) => {
    136             _resolve = resolve;
    137             _reject = reject;
    138         });
    139         if (p.#isPromiseA(value)) {
    140             value.then(_resolve, _reject)
    141         } else {
    142             _resolve(value);
    143         }
    144         return p;
    145     }
    146 
    147     static reject = (reason) => {
    148         return new MyPromise((resolve, reject) => {
    149             reject(reason);
    150         })
    151     }
    152 
    153     static all = (iterable) => {
    154         let _resolve, _reject;
    155         const p = new MyPromise((res, rej) => {
    156             _resolve = res;
    157             _reject = rej;
    158         });
    159         let successCount = 0;
    160         let count = 0;
    161         let data = [];
    162         for (const item of iterable) {
    163             const i = count;
    164             count++;
    165             MyPromise.resolve(item).then(res=>{
    166                 successCount++;
    167                 data[i] = res;
    168                 if(count === successCount) {
    169                     _resolve(data);
    170                 }
    171             }, _reject )
    172         };
    173         if (count === 0) {
    174             _resolve(data);
    175         }
    176         return p;
    177     }
    178 }
    179 
    180 const a = new MyPromise((resolve, reject) => {
    181     // resolve(123)
    182     // reject('error')
    183     // setTimeout(() => {
    184     //     resolve(123);
    185     // }, 1000);
    186     // throw 'error'
    187 });

     

标签:resolve,return,.#,value,callBack,Promise,reject,手写
From: https://www.cnblogs.com/dadouF4/p/18364886

相关文章

  • lua版promise实现 - 结束
    相比V1版本这边做了以下修改:1)函数命名尽量与js版保持一致,js中的then在这边叫Next(因为then是lua的关键字)2)m_DoNextObj这边变成了一个列表,这样改动的结果就是:之前对象间会组成单向链表;这边是一个单向的树。3)m_DoNextObj.run函数这边改成了m_OnFulfilled和m_OnRejected函数(......
  • lua版promise实现3 - 条件判断例子
    针对:先加载资源A,加载完A再加载资源B,加载完B再加载资源C。现在加需求了,如果加载资源A的时间不超过3s,那说明当前设备性能不错,会额外再加载高品质资源A2,A3,然后再加载B。 localobj1=PromiseV1.new()localtime1=os.time()AsyncLoadRes("ResA",function(textA)obj1:S......
  • KNN图像识别实例--手写数字识别
    目录前言一、导入库二、导入图像并处理1.导入图像2.提取出图像中的数字3.将列表转换成数组4.获取特征数据集5.获取标签数据三、使用KNN模型1.创建KNN模型并训练2.KNN模型出厂前测试3.使用测试集对KNN模型进行测试四、传入单个图像,使用该模型进行识别1.导入图像......
  • js异步之Promise使用
    Promise是异步编程的一种解决方案,是一个对象,可以获取异步操作的消息,大大改善了异步编程的困难,避免了回调地狱,比传统的解决方案回调函数和事件更合理和更强大。从语法上讲,Promise是一个对象,它可以获取异步操作的消息。提供了一个统一的API,各种异步操作都可以用同样的方法进行处理......
  • lua版promise实现 - 从异步回调多层嵌套开始
    异步回调代码,很容易就写出下面这样的不断嵌套的代码。如果还夹杂着各种逻辑的话,可读性会很差,还容易出错。AsyncLoadRes("ResA",function(textA)print("ResAloadfinish")AsyncLoadRes("ResB",function(textB)print("ResBloadfinish")AsyncLoad......
  • 【Java手写RPC框架系列-1】—— 基础知识准备:RPC+Netty
    代码随想录知识星球介绍https://articles.zsxq.com/id_m76jd72243bi.html基于Netty手写实现RPChttps://www.cnblogs.com/mic112/p/15565795.html项目背景与介绍RPC:远程过程调用协议:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序......
  • JS Promise 一分钟带你深度理解
    JSPromise一分钟带你深度理解文章目录JSPromise一分钟带你深度理解一、什么是Promise?二、为什么使用Promise?三、基础知识四、创建Promise五、Promise使用1、链式调用2、顺序执行3、处理多个Promise4、错误处理六、高级用法七、最佳实践八......
  • AJAX - 利用XML和Promise封装简易版axios,了解axios底层原理
     AJAX原理-XMLHttpRequest定义:XMLHttpRequest(XHR)对象用于与服务器交互。通过XMLHttpRequest可以在不刷新页面的情况下请求特定URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest 在 AJAX 编程中被大量使用。关系:axios内部采用......
  • 手写Redis缓存系统,第一章:基于http协议实现的缓存系统
    关系描述关系图文本描述main包依赖cache包依赖http包流程:main包的main函数调用cache.New("inmemory")创建一个缓存实例。main包的main函数将缓存实例传递给http.New(c)创建一个Server实例。Server实例调用Listen方法启动HTTP服务器......
  • promise.catch
    在JavaScript中,如果你在Promise链中使用了catch,并且catch捕获到一个异常后,后面的then仍然会被执行,但有一些具体的行为取决于catch中的操作。1、当promise.catch捕获到异常并返回一个值,那么后续的then会继续执行,并且接收catch中返回的值作为输入。如:newPromise((......