手写Promise简易版
话不多说,直接上代码
通过ES5的模块化封装,向外暴露一个属性
(function(window){
const PENDING = 'pending';
const RESOLVED = 'fulfilled'
const REJECTED = 'rejected'
function MyPromise(excutor){
const self = this; //保存Promise对象,防止异步执行时,拿不到数据和方法,必要
self.value = undefined;
self.status = PENDING;
self.callbacks = [] //当状态没有发生改变时,需要储存起回调函数, 在then方法中获取回调函数
function resolve(value){
self.value = value;
self.status = RESOLVED;
self.callbacks.map(cb => {
setTimeout(() => { //定时器模拟异步执行,必须保证回调异步执行,否则顺序就乱了
cb.onResolved(self.value)
})
}) //执行保存起来的成功回调函数
}
function reject(value){
self.value = value;
self.status = REJECTED ;
self.callbacks.map(cb => {
setTimeout(() => {
cb.onRejected (self.value)
})
})//执行保存起来的失败的回调函数
}
try{ //若在执行器函数中主动抛出错误,需要捕获错误,并把状态更改为rejected
excutor(resolve,reject)
} catch (error){
reject(error)
}
}
MyPromise.prototype.then = function( onResolved,onRejected ){
const self = this//保存当前的Promise对象
return new Promise(resolve,reject){
onResolved = onResolved === 'function' ? onResolved : v => v
onRejected = onRejected === 'function' ? onRejected : error => {throw error} //实现异常透传
//判断当前的状态
//假如Promise执行的异步任务,then方法是同步方法,那么当时Promise的状态为pending,所以不能执行回调,此时需要保存
if(self.status === PENDING){
// 这里只是把回调保存了起来,并没有改变当前的Promise对象,所以得进一步处理,处理和成功得处理类似
self.callbacks.push({onResolved,onRejected}) //保存每一个then方法为一个对象,包含onResolved,onRejected两个函数
} else if(self.status === RESOLVED){
//1. 保证then中的回调异步执行,加一个setTimeout
//2. 在onResolved中如果主动抛出错误,需要捕获错误
//3. 根据Promise对象返回的结果,来决定下一个then中执行成功还是失败的回调
//4. 如果上一个Promise返回的是一个值,如return 2,那么直接用resolve(2)执行
//5. 如果上一个Promise返回的是一个promise对象,那么要通过promise.then 来获取promise的执行结果
setTimeout(() => {
try {
const result = onResolved(self.value)
if( result instanceof MyPromise){ //判断返回值是不是Promise对象
//返回一个Promise对象
result.then(
value => { //返回值是Promise对象,并且是成功的,那么就会执行这一个函数
resolve(self.value)
}
error => { //返回值是Promise对象,并且是失败的,那么就会执行这一个函数
rejecte(self.value)
}
)
}else { //返回的不是一个Promise对象
resolve(self.value)
}
} catch (error) {
//与成功的处理一样,只需要更改一下回调函数,太长就不写了
}
})
} else { //rejected状态}
}
}
window.MyPromise = MyPromise //向外暴露方法
})(window)
到这里就差不多写完简易的promise了,了解了原理也能更好的使用promise
欢迎指正,若有不清楚,也可评论指出
手写Promise简易版的更多相关文章
- 来,我们手写一个简易版的mock.js吧(模拟fetch && Ajax请求)
预期的mock的使用方式 首先我们从使用的角度出发,思考编码过程 M1. 通过配置文件配置url和response M2. 自动检测环境为开发环境时启动Mock.js M3. mock代码能直接覆盖g ...
- 手写spring(简易版)
本文版权归 远方的风lyh和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作,如有错误之处忘不吝批评指正! 理解Spring本质: 相信之前在使用spring的时候大家都配置web.x ...
- 手写一个简易版Tomcat
前言 Tomcat Write MyTomcat Tomcat是非常流行的Web Server,它还是一个满足Servlet规范的容器.那么想一想,Tomcat和我们的Web应用是什么关系? 从感性上 ...
- 我手写的简易tomcat
前述 自己手写的简易的tomcat,实现了tomcat的基本响应功能,项目代码已经上传到我的Github,刚刚开始学习这里,当前还存在很多问题 项目简述及代码 当我们的Web运行的时候,从浏览器发出的 ...
- 手写Promise A+ 规范
基于ES6语法手写promise A+ 规范,源码实现 class Promise { constructor(excutorCallBack) { this.status = 'pending'; ...
- 手写promise
写在前面: 在目前的前端分开中,我们对于异步方法的使用越来越频繁,那么如果处理异步方法的返回结果,如果优雅的进行异步处理对于一个合格的前端开发者而言就显得尤为重要,其中在面试中被问道最多的就是对Pro ...
- 手写 Promise
在上一章节中我们了解了 Promise 的一些易错点,在这一章节中,我们会通过手写一个符合 Promise/A+ 规范的 Promise 来深入理解它,并且手写 Promise 也是一道大厂常考题,在 ...
- 手写Promise看着一篇就足够了
目录 概要 博客思路 API的特性与手写源码 构造函数 then catch Promise.resolved Promise.rejected Promise.all Promise.race 概要 ...
- 手写Promise中then方法返回的结果或者规律
1. Promise中then()方法返回来的结果或者规律 我们知道 promise 的 then 方法返回来的结果值[result]是由: 它指定的回调函数的结果决定的 2.比如说下面这一段代码 l ...
随机推荐
- MapReduce之WritableComparable排序
@ 目录 排序概述 获取Mapper输出的key的比较器(源码) 案例实操(区内排序) 自定义排序器,使用降序 排序概述 排序是MapReduce框架中最重要的操作之一. Map Task和Reduc ...
- PHP 中的字符串变量
PHP 字符串变量 字符串变量用于存储并处理文本. PHP 中的字符串变量 字符串变量用于包含有字符的值. 在创建字符串之后,我们就可以对它进行操作了.您可以直接在函数中使用字符串,或者把它存储在变量 ...
- PHP array_diff_assoc() 函数
实例 比较两个数组的键名和键值,并返回差集: <?php$a1=array("a"=>"red","b"=>"g ...
- 6.28 NOI模拟赛 好题 状压dp 随机化
算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...
- 性能分析(3)- 短时进程导致用户 CPU 使用率过高案例
性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 系统架构背景 VM1:用作 Web 服务器,来模拟 ...
- Armv8-A Memory management
本文介绍Armv8-A的内存管理.内存管理指的是在系统中,内存访问是如何实现的. 使用内存管理机制,可以让每个应用之间的内存地址分离,即sandbox application,也可以让多个在物理内存上 ...
- 【FZYZOJ】数论课堂 题解(约数个数定理)
前言:想了两个小时orz,最后才想到要用约数个数定理…… ------------- 题目大意: 给定$n,q,A[1],A[2],A[3]$ 现有$A[i]=(A[i-1]+A[i-2]+A[i-3 ...
- Bystack跨链技术源码解读
Bystack是由比原链团队提出的一主多侧链架构的BaaS平台.其将区块链应用分为三层架构:底层账本层,侧链扩展层,业务适配层.底层账本层为Layer1,即为目前比较成熟的采用POW共识的Bytom公 ...
- 洛谷 P4198 楼房重建
思路 此题可转化为以下模型 给定序列\(a[1...n]\),支持单点修改,每次求区间单调栈大小 \(n,Q\le 10^5\) 区间单调栈是什么呢?对于一个区间,建立一个栈,首先将第一个元素入栈,从 ...
- Go之Gorm和BeegoORM简介及配置使用
简介 ORM Object-Relationl Mapping, 它的作用是映射数据库和对象之间的关系,方便我们在实现数据库操作的时候不用去写复杂的sql语句,把对数据库的操作上升到对于对象的操作 G ...