js中promise原理及手动基本实现_V3
前言
前一章讲到通过订阅-发布模式,解决了resolve被setTimeout包裹,导致最终结果出不来的bug。但是,原生的promise还有一个很重要的特性,就是可以进行链式调用,then方法的执行结果也是一个promise对象。下面进入本章的正题。
前一章链接:https://blog.csdn.net/weixin_42344533/article/details/117622308
后一章链接:https://blog.csdn.net/weixin_42344533/article/details/117636782
过程
1、上一个版本实现的promise并不能进行链式调用,因为then没有返回promise对象,所以会报错。
2、版本3中实现了then方法的链式调用,效果图如下。
3、 版本3的then方法链式调用实现,主要是对then方法的返回值进行包装(promise包装)+递归加锁的方式实现。所以接下来,就对版本二的then方法进行改造。
4、全局handlePromise方法实现,主要通过递归加锁方式。
总结
then方法的链式调用,主要实现思路有两个点,一个是对then方法的返回值进行promise对象包装,另一个是对上一个then方法的返回值进行递归加锁处理。
实现源码myPromise.js:
const RESOLVE = 'resolved'
const REJECT = 'rejected'
const PENDING = 'pending'const handlePromise = (result, newPromise, resolve, reject) => {if (result === newPromise) {throw new Error('can not return oneself')}if ((typeof result === "object" && result != null) || typeof result === "function") {let lock = falseconst then = result.thenif (typeof then === "function") {then.call(result,r => {if (lock) returnhandlePromise(r, newPromise, resolve, reject)lock = true},e => {if (lock) returnreject(e)lock = true})} else {resolve(result)}} else {resolve(result)}
}function selfPromise(exe) {this.status = PENDINGthis.result = undefinedthis.reason = undefinedthis.resolveAsyList = []this.rejectAsyList = []this.init = (exe) => {const resolve = (result) => {if (this.status === PENDING) {this.result = resultthis.status = RESOLVEthis.resolveAsyList.map(resolveAsy => {resolveAsy()})}}const reject = (reason) => {if (this.status === PENDING) {this.reason = reasonthis.status = REJECTthis.rejectAsyList.map(rejectAsy => {rejectAsy()})}}try {exe(resolve, reject);} catch (error) {reject(error)}}this.then = (onResolve, onReject) => {const newPromise = new selfPromise((resolve, reject) => {if (this.status === RESOLVE) {setTimeout(() => {const result = onResolve(this.result)handlePromise(result, newPromise, resolve, reject)}, 0)}if (this.status === REJECT) {setTimeout(() => {const result = onReject(this.reason)handlePromise(result, newPromise, resolve, reject)}, 0)}if (this.status === PENDING) {this.resolveAsyList.push(() => {const result = onResolve(this.result)handlePromise(result, newPromise, resolve, reject)})this.rejectAsyList.push(() => {const result = onReject(this.reason)handlePromise(result, newPromise, resolve, reject)})}})return newPromise}this.init(exe)
}module.exports = selfPromise
测试实例test.js:
const myPromise = require('./myPromise_v3')var test = new myPromise((resolve,reject)=>{setTimeout(()=>{resolve("这是手动实现的promise")},1000)
})test.then(res=>{console.log(res)return "这是版本3的then链式调用返回1"}).then(res=>{console.log(res)return "这是版本3的then链式调用返回2"}).then(res=>{console.log(res)})console.log("同步代码")
下一章将在版本3的基础上实现原生promise的catch的方法,同时对整个promise对象进行异常处理的优化。
后一章链接:https://blog.csdn.net/weixin_42344533/article/details/117636782
js中promise原理及手动基本实现_V3相关推荐
- js中promise原理及手动基本实现_V1
前言 这几天面试过程,有个面试官突然跟我抠上了promise的实现原理,虽然有所准备,但是没能清晰地说出其中的原理,所以有点遗憾!!!,但是事已至此,只能默默去查了相关资料深入其中了解一番.因此就有了 ...
- js中promise原理及手动基本实现_V2
前言 上一章中已经讲完了promise最基本实现的原理,本章将在其基础上进行进一步的扩展,以满足更多的使用场景,源码在文章最后哦. 上一章链接:https://blog.csdn.net/weixin ...
- js中promise原理及手动基本实现_V4
前言 上一章,我们实现了promise的then方法链式调用,本章节就对原型promise的catch方法进行简单的实现,同时对对象进行一个整体的异常处理优化,以提高对象整体的健壮度. 上一章链接:h ...
- JS中Promise函数then的奥秘探究
JS中Promise函数then的奥秘探究 Promise概述 Promise对象是CommonJS工作组提出的一种规范,目的是为异步操作提供统一接口. 那么,什么是Promises? 首先,它是一个 ...
- js中 new原理及实现
在js中,我们通过new运算符来创建一个对象,它是一个高频的操作.我们一般只是去用它,而很少关注它是如何实现的,它的工作机制是什么. 1 简介 本文介绍new的功能,用法,补充介绍不加new也同样也创 ...
- Js中Promise用法
promise是用来解决Js中的异步问题的.基本结构如下: function a() {return new Promise((resolve, reject) => {//dosomethin ...
- js中promise的用法
promise promise是ES6引进的异步编程解决方案,是一个构造函数,可以实例化对象,可以解决回调地狱的问题. 首先我们看一下promise的实例化对象是什么 let P = new Prom ...
- js中几种实用的跨域方法原理详解
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- php模拟红绿灯,JS 中使用Promise 实现红绿灯详解
本文通过实例代码给大家介绍了JS 中使用Promise 实现红绿灯效果,在文中给大家介绍了一个promise用法例子,需要的朋友可以参考下,希望能帮助到大家. 要求使用promise 实现红绿灯颜色的 ...
最新文章
- Flex 元数据标签使用
- 急速上线 Serverless 钉钉机器人“防疫精灵”
- 减少模型方差的方法借鉴
- 【笔记】 感受野与权值共享 摄像头标定 相机坐标与世界坐标
- ESP8266-01学习笔记01:如何使用USB转串口对ESP-01进行入门调试、烧录固件?
- P4301 [CQOI2013] 新Nim游戏
- java 线程安全性_我如何测试Java类的线程安全性
- 农信银高莉:农信科技共享计划
- CentOS6.5升级内核到3.10.28
- 95-190-640-源码-窗口操作符-WindowOperator
- AUTOCAD——成组命令
- ssh连接openwrt_如何将SSH无密码连接到OpenWrt路由器?
- USB(九)2022-03-01
- PHP课程设计概要(也许毕业设计也可以用,往正式方向走)想起来在做补充 中规中矩,没有特色
- 思岚A1与A2性能及建图测试比较
- cu116安装gpu版pytorch
- 【微信小程序】判断手机号是否合法
- A股暴跌三日市值蒸发4.2万亿 股民人均浮亏超2万
- Docker+Jenkins+GIT+Tomcat实战持续化集成
- 水星MW150US安装Linux驱动
热门文章
- Linux内存清道夫--OOM Killer
- python爬虫入库到帝国cms_说下Python入门
- less面试_资深面试官告诉你:面试时千万不要说这七句话
- MHDD找不到硬盘的解决方案
- Activiti6自学之路(九)——请假申请和请假审批数据库表设计
- 微信控制家庭智能小管家机器人(附语音聊天、人脸检测)
- [深度学习] 初探—学习记录(应用层)
- 量化交易——均值回归策略
- 巨头的云计算正在吃掉世界!疯狂圈地后,谁将是下一个霸主?
- python爬虫功能、识别200张图片中的物体_python爬虫功能、识别200张图片中的物体_python爬虫怎么识别...