热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

手写promise第一天

2020-09-22手写promise第一天status:用pendingfulfilledrejected3中情况分别对应等待成功失败状态只能由等待改变为成功或者失败且不可逆ex


2020-09-22
手写promise第一天
status:

  • 用pending fulfilled rejected 3中情况分别对应 等待 成功 失败

  • 状态只能由等待改变为成功或者失败 且不可逆


executor执行器:

在promise的构造函数中接收一个执行器函数 这个函数是同步执行的

这个执行器在执行时可以接收两个参数 分别是promise类中的resolve和reject


resolve&reject:

在执行器执行过程中,如果获取到需要的数据 那么执行resolve函数并将数据当做参数传入

resolve函数会将状态status改为fulfilled并且把数据存入到value中

当执行到resolve时 如果在成功回调函数队列中有回调函数 那么依次执行他们

reject同理


then:

promise中的then函数 接收两个参数分别是成功和失败的回调

同时新建一个新的promise对象 并且把这个then函数要做的事情作为 新promise对象的执行器函数传入

在这个then函数中判断当前promise的状态 如果是成功 那么执行成功回调并将value传入

成功回调函数可以返回一个值到 可以用一个变量接收作为新promise对象的resolve的参数传入

如果当前promise的状态是rejected 那么同理调用reject方法

如果状态是pending 说明当前promise还没有执行resolve或reject

将then传入的成功回调和失败回调都存到对应的回调队列里 在resolve实行的时候再去调用


resolvePromise处理器:

由于用很多种情况都要去处理resolve 所以有必要提取出来作为一个单独的函数便于复用

处理器中判断成功回调返回的值是普通值 那么可以直接执行新promise的resolve或reject方法

如果返回值是一个promise对象 那么要用这个promise对象的then方法判断这个对象目前是成功还是失败 再调用对应方法

如果返回值是一个promise对象且跟then方法中的promise对象相同 那么就死循环了 应该抛出一个错误


总结:

  • 还没有处理then中的异步问题

  • 还没有实现promise.all等方法

  • then中逻辑还是有点乱 明天继续捋

const PENDING = 'pengding';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
status = PENDING; // 当前promise的状态
value = undefined; // 当前promise的值
reason = undefined; // 当前promise如果失败 失败的原因
successCallbacks = []; // 如果异步 那么将回调存入到对应回调库中
rejectCallbacks = [];
// promise 的构造函数接受一个执行器 这个执行器会立即执行
constructor(executor) {
// 这个执行器接收两个参数 第一个参数是执行成功 第二个是失败
// 在执行器执行的过程中如果resolve执行 那么这个promise成功
executor(this.resolve, this.reject);
}
// 成功调用resolve方法 接收一个参数作为这个promise的返回值存在promise对象中
resolve = data => {
// 一旦status状态不是pending 那么就不再执行 保证状态不可逆
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = data; // 将promise成功获得的数据存在value中
// 判断成功回调函数库中是否用未执行的函数 有的话依次执行
while (this.successCallbacks.length) {
this.successCallbacks.shift()(this.value);
}
}
// 同resolve
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.rejectCallbacks.length) this.rejectCallbacks.shift()(this.reason);
}
// then方法 接收两个函数作为参数 第一个是成功的回调
then = (successCallback, rejectCallback) => {
// then方法 返回的是一个新的promise对象 所以在执行then的时候 new一个新的promise
// 同样的 这个新promise的执行器也会立即执行
let promise2 = new MyPromise((resolve, reject) => {
// 当执行到then方法时候 status已经是FULFILLED说明promise已经执行成功
// 直接执行成功的回调
// 同时将成功回调的返回值传递给下一个promise的resolve方法
if (this.status === FULFILLED) {
setTimeout(() => {
const thenReturnVal = successCallback(this.value);
resolvePromise(promise2, thenReturnVal, resolve, reject);
}, 0);
} else if (this.status === REJECTED) {
const thenRejectVal = rejectCallback(this.reason);
resolvePromise(thenRejectVal, resolve, reject);
} else {
// 如果执行到then的时候状态还是pending 那么 先把成功和失败的回调都存入到对应的回调库中去
// 第27行 如果resolve是异步的话 等异步结束接收到值再将回调函数从库中取出依次执行
this.successCallbacks.push(successCallback);
this.rejectCallbacks.push(rejectCallback);
}
});
this.promise2 = promise2;
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
reject(new TypeError('重复调用自己了哦~'));
}
if (x instanceof MyPromise) {
// 是promise对象 那需要调用Promise的then方法判断这个promise是否成功
// 如果成功 调用resolve方法 并且把值传递下去 如果失败 调用reject并且把原因传递下去
x.then(value => resolve(value), reason => reject(reason));
// x.then(resolve, reject);
} else {
resolve(x);
}
}
// (resolve, reject) => {resolve('666')} 是一个执行器函数 会立即执行
// 两个参数分别是promise内部传入的
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(66666);
}, 2000);
})
const promise33 = new MyPromise((resolve, reject) => {
resolve('promise33')
})
// 第一个then调用时 传入两个回调函数
// 第一个then函数内部立刻创建一个新的promise对象 并且then传入的两个函数
// 和then中的所有逻辑代码都作为新promise对象的执行器立即执行
// 如果promise成功 那么执行第一个也就是53行的successCallback
let p1 = promise.then(data => {
console.log(data);
// 这个return会作为successCallback的返回值传入新的promise中
// 在新promise调用resolve方法时 可以当做值传递给新promise的value
setTimeout(() => {
return promise33;
}, 2000);
}, reason => {
console.log(reason);
}) // 执行完第一个then后 会返回一个新的promise
p1.then((thenReturnVal) => { // 再次调用then是调用新promise的then方法
// 同时这个新promise的resolve方法接收上一个then方法successCallback的返回值作为value
console.log(thenReturnVal);
return 'then 3'
}, (thenRejectVal) => {
console.log(thenRejectVal);
})

 



推荐阅读
  • 一、什么是闭包?有什么作用什么是闭包闭包是定义在一个函数内部的函数,它可以访问父级函数的内部变量。当一个闭包被创建时,会关联一个作用域—— ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 006_Redis的List数据类型
    1.List类型是一个链表结构的集合,主要功能有push,pop,获取元素等。List类型是一个双端链表的结构,我们可以通过相关操作进行集合的头部或者尾部添加删除元素,List的设 ... [详细]
  • 在编写业务代码时,常常会遇到复杂的业务逻辑导致代码冗长混乱的情况。为了解决这个问题,可以利用中间件模式来简化代码逻辑。中间件模式可以帮助我们更好地设计架构和代码,提高代码质量。本文介绍了中间件模式的基本概念和用法。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • ECMA262规定typeof操作符的返回值和instanceof的使用方法
    本文介绍了ECMA262规定的typeof操作符对不同类型的变量的返回值,以及instanceof操作符的使用方法。同时还提到了在不同浏览器中对正则表达式应用typeof操作符的返回值的差异。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • 本文是一篇翻译文章,介绍了async/await的用法和特点。async关键字被放置在函数前面,意味着该函数总是返回一个promise。文章还提到了可以显式返回一个promise的方法。该特性使得async/await更易于理解和使用。本文还提到了一些可能的错误,并希望读者能够指正。 ... [详细]
  • 前段时间做一个项目,需求是对每个视频添加预览图,这个问题最终选择方案是:用canvas.toDataYRL();来做转换获取视频的一个截图,添加到页面中,达到自动添加预览图的目的。 ... [详细]
  • 1简介本文结合数字信号处理课程和Matlab程序设计课程的相关知识,给出了基于Matlab的音乐播放器的总体设计方案,介绍了播放器主要模块的功能,设计与实现方法.我们将该设 ... [详细]
  • 巧用arguments在Javascript的函数中有个名为arguments的类数组对象。它看起来是那么的诡异而且名不经传,但众多的Javascript库都使用着它强大的功能。所 ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
author-avatar
糖糖糖开水
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有