前言

前一章讲到通过订阅-发布模式,解决了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相关推荐

  1. js中promise原理及手动基本实现_V1

    前言 这几天面试过程,有个面试官突然跟我抠上了promise的实现原理,虽然有所准备,但是没能清晰地说出其中的原理,所以有点遗憾!!!,但是事已至此,只能默默去查了相关资料深入其中了解一番.因此就有了 ...

  2. js中promise原理及手动基本实现_V2

    前言 上一章中已经讲完了promise最基本实现的原理,本章将在其基础上进行进一步的扩展,以满足更多的使用场景,源码在文章最后哦. 上一章链接:https://blog.csdn.net/weixin ...

  3. js中promise原理及手动基本实现_V4

    前言 上一章,我们实现了promise的then方法链式调用,本章节就对原型promise的catch方法进行简单的实现,同时对对象进行一个整体的异常处理优化,以提高对象整体的健壮度. 上一章链接:h ...

  4. JS中Promise函数then的奥秘探究

    JS中Promise函数then的奥秘探究 Promise概述 Promise对象是CommonJS工作组提出的一种规范,目的是为异步操作提供统一接口. 那么,什么是Promises? 首先,它是一个 ...

  5. js中 new原理及实现

    在js中,我们通过new运算符来创建一个对象,它是一个高频的操作.我们一般只是去用它,而很少关注它是如何实现的,它的工作机制是什么. 1 简介 本文介绍new的功能,用法,补充介绍不加new也同样也创 ...

  6. Js中Promise用法

    promise是用来解决Js中的异步问题的.基本结构如下: function a() {return new Promise((resolve, reject) => {//dosomethin ...

  7. js中promise的用法

    promise promise是ES6引进的异步编程解决方案,是一个构造函数,可以实例化对象,可以解决回调地狱的问题. 首先我们看一下promise的实例化对象是什么 let P = new Prom ...

  8. js中几种实用的跨域方法原理详解

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  9. php模拟红绿灯,JS 中使用Promise 实现红绿灯详解

    本文通过实例代码给大家介绍了JS 中使用Promise 实现红绿灯效果,在文中给大家介绍了一个promise用法例子,需要的朋友可以参考下,希望能帮助到大家. 要求使用promise 实现红绿灯颜色的 ...

最新文章

  1. Flex 元数据标签使用
  2. 急速上线 Serverless 钉钉机器人“防疫精灵”
  3. 减少模型方差的方法借鉴
  4. 【笔记】 感受野与权值共享 摄像头标定 相机坐标与世界坐标
  5. ESP8266-01学习笔记01:如何使用USB转串口对ESP-01进行入门调试、烧录固件?
  6. P4301 [CQOI2013] 新Nim游戏
  7. java 线程安全性_我如何测试Java类的线程安全性
  8. 农信银高莉:农信科技共享计划
  9. CentOS6.5升级内核到3.10.28
  10. 95-190-640-源码-窗口操作符-WindowOperator
  11. AUTOCAD——成组命令
  12. ssh连接openwrt_如何将SSH无密码连接到OpenWrt路由器?
  13. USB(九)2022-03-01
  14. PHP课程设计概要(也许毕业设计也可以用,往正式方向走)想起来在做补充 中规中矩,没有特色
  15. 思岚A1与A2性能及建图测试比较
  16. cu116安装gpu版pytorch
  17. 【微信小程序】判断手机号是否合法
  18. A股暴跌三日市值蒸发4.2万亿 股民人均浮亏超2万
  19. Docker+Jenkins+GIT+Tomcat实战持续化集成
  20. 水星MW150US安装Linux驱动

热门文章

  1. Linux内存清道夫--OOM Killer
  2. python爬虫入库到帝国cms_说下Python入门
  3. less面试_资深面试官告诉你:面试时千万不要说这七句话
  4. MHDD找不到硬盘的解决方案
  5. Activiti6自学之路(九)——请假申请和请假审批数据库表设计
  6. 微信控制家庭智能小管家机器人(附语音聊天、人脸检测)
  7. [深度学习] 初探—学习记录(应用层)
  8. 量化交易——均值回归策略
  9. 巨头的云计算正在吃掉世界!疯狂圈地后,谁将是下一个霸主?
  10. python爬虫功能、识别200张图片中的物体_python爬虫功能、识别200张图片中的物体_python爬虫怎么识别...