唯心主义蠢货的[js知识总结] 手写一个promise

2023-10-14 01:10

本文主要是介绍唯心主义蠢货的[js知识总结] 手写一个promise,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

promise

用法分析

在这里插入图片描述

流程分析
  • promise通过一个接收一个函数进行实例化
  • 此函数接收两个参数,一个为fulfill时进行的处理,一个为reject时进行的处理
  • 当exector函数在promise内部进行执行时,修改promise的value和status
  • 在then和catch中,根据status进行条件判断
关于优化的点
  • exector为异步调用时
  • 如何实现then的链式调用

代码基本实现

  • promise接收一个exector,并在内部进行value和status的改变 在这里插入图片描述

  • then进行resolve的实现
    在这里插入图片描述

  • catch进行reject的实现
    在这里插入图片描述

代码优化

关于异步

当出现异步操作时,即promise先对exector内部逻辑进行事件注册,然后对then和catch进行执行,当exector内部需要执行时再进行执行,也即需要先对then和catch对应的事件进行保留,再根据exector的改变进行调用

  • 在promise内声明两个操作数组
    在这里插入图片描述

  • 在then中加入pending状态下,将操作事件压入的分支

  • 在promise中当status改变时,对操作数组内的事件进行执行

关于链式操作
  • 链式操作的关键在于在操作时,返回一个promise

  • promise的exector函数,为对当前then传入的fulfulled和rejected函数的处理
    1570421403141.png"

  • promise的value和status值,为上一步即fulfulled和rejected的返回值

    • 如果返回值为非promise类型,则通过resolve状态改变函数,将此返回值作为参数传入

    • 如果返回值为promise类型,则通过x.then(resolve,reject) 对其内部的值进行改变(由于resolve和reject的this都对应着返回值promise,x内部的操作即对返回promise的value和status的改变)

    • 如果出现错误,则也将其作为下一个promise的成功resolve的参数进行传递

代码

function promise( exector ) {let _this = this;this.value = null; // 处理值this.status = 'pending'; //当前状态this.reason = null; // 失败原因this.onFulfilledCallback = []; // resolve处理数组this.onRejectCallback = []; // reject处理数组//当且仅当 status为pending时 状态才可以改变  即一旦成功或失败 则不允许改变状态//resolve函数  改变value  改变状态function resolve( value ) {if (_this.status == 'pending') {_this.value = value;_this.status = 'resolve';_this.onFulfilledCallback.forEach(fn => {fn(_this.value); // 根据函数注册的顺序执行});}}// reject函数  改变reason  改变状态function reject( reason ) {if (_this.status == 'pending') {_this.reason = reason;_this.status = 'reject';_this.onRejectCallback.forEach(fn => {fn(_this.reason);});}}try {exector(resolve, reject);  //执行  进行状态的改变} catch ( e ) {reject(e);  // 直接跳到reject状态}}promise.prototype.then = function ( onFulfilled, onRejected ) {let _this = this;onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function ( value ) { };  // 判断是否为函数onRejected = typeof onRejected === 'function' ? onRejected : function ( reason ) {  };if (_this.status == 'resolve') {return new promise(( resolve, reject ) => {try {let x = onFulfilled(_this.value);//处理这一步的操作if( x instanceof promise){  //但当前返回值为promise时x.then(resolve,reject);//因为resolve和reject都指向外部this,所以在x中改变value和status即对外部进行改变}else{resolve(x);  // 改变返回promise的value和status}}catch ( e ) {reject(e);}});}if (_this.status == 'reject') {return new promise(( resolve, reject ) => {try {let x =onRejected(_this.value);if(x instanceof promise){x.then(resolve,reject);  }else{resolve(x);}}catch ( e ) {reject(e);}});}if (_this.status == 'pending') {return new promise(( resolve, reject ) => {_this.onFulfilledCallback.push(() =>{let x = onFulfilled(_this.value);if( x instanceof  promise){x.then(resolve,reject);}else{resolve(x);}});_this.onRejectCallback.push( () =>{let x = onRejected(_this.reason);if(x instanceof promise){x.then(resolve,reject);}else{resolve(x);}});});}};promise.prototype.catch = function ( error ) {return this.then(null, error);};function test( resolve, reject ) {let i = Math.random() * 10;setTimeout(function () {if (i > 5) {resolve(i);} else {reject(i);};}, 500);console.log('123456');}function test2( x ) {let i = Math.random() * 100;return new promise(function ( resolve,reject ) {console.log("略略略"+x);resolve(x+1);});}let p = new promise(test);// p.then(function ( value ) {//     console.log('resolve' + value);//     return " resolve"+value;// },function ( error ) {//     console.log('error' + error);//     return " error"+error;// }).then(function ( value ) {//     console.log('resolve' + value);// }).catch(function ( error ) {//     console.log('error' + error);// });p.then(test2).then(test2);

这篇关于唯心主义蠢货的[js知识总结] 手写一个promise的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/207093

相关文章

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

java常见报错及解决方案总结

《java常见报错及解决方案总结》:本文主要介绍Java编程中常见错误类型及示例,包括语法错误、空指针异常、数组下标越界、类型转换异常、文件未找到异常、除以零异常、非法线程操作异常、方法未定义异常... 目录1. 语法错误 (Syntax Errors)示例 1:解决方案:2. 空指针异常 (NullPoi

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

Java反转字符串的五种方法总结

《Java反转字符串的五种方法总结》:本文主要介绍五种在Java中反转字符串的方法,包括使用StringBuilder的reverse()方法、字符数组、自定义StringBuilder方法、直接... 目录前言方法一:使用StringBuilder的reverse()方法方法二:使用字符数组方法三:使用自

国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)

《国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)》本文给大家利用deepseek模型搭建私有知识问答库的详细步骤和遇到的问题及解决办法,感兴趣的朋友一起看看吧... 目录1. 第1步大家在安装完ollama后,需要到系统环境变量中添加两个变量2. 第3步 “在cmd中

Javascript访问Promise对象返回值的操作方法

《Javascript访问Promise对象返回值的操作方法》这篇文章介绍了如何在JavaScript中使用Promise对象来处理异步操作,通过使用fetch()方法和Promise对象,我们可以从... 目录在Javascript中,什么是Promise1- then() 链式操作2- 在之后的代码中使

Python依赖库的几种离线安装方法总结

《Python依赖库的几种离线安装方法总结》:本文主要介绍如何在Python中使用pip工具进行依赖库的安装和管理,包括如何导出和导入依赖包列表、如何下载和安装单个或多个库包及其依赖,以及如何指定... 目录前言一、如何copy一个python环境二、如何下载一个包及其依赖并安装三、如何导出requirem

Node.js net模块的使用示例

《Node.jsnet模块的使用示例》本文主要介绍了Node.jsnet模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下... 目录简介引入 net 模块核心概念TCP (传输控制协议)Socket服务器TCP 服务器创建基本服务器服务器配置选项服

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

Rust格式化输出方式总结

《Rust格式化输出方式总结》Rust提供了强大的格式化输出功能,通过std::fmt模块和相关的宏来实现,主要的输出宏包括println!和format!,它们支持多种格式化占位符,如{}、{:?}... 目录Rust格式化输出方式基本的格式化输出格式化占位符Format 特性总结Rust格式化输出方式