手写符合Promise/A+规范的Promise
const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected"; function MyPromise(fn){
const that = this;
that.state = PENDING;
that.value = null;
that.resolvedCallbacks = [];
that.rejectedCallbacks = [];
function resolve(value){
// 判断传入的值是否为 Promise 类型
if( value instanceof MyPromise){
return value.then(resolve, reject)
}
// 为了保证函数的执行顺序,需要将两个函数体代码使用 setTimeout 包裹起来
setTimeout(()=>{
// 只有等待状态才可以改变状态
if(that.state == PENDING){
// 将当前状态更改为对应状态,并且将传入的值赋值给 value
that.state = RESOLVED;
that.value = value;
// 遍历回调数组并执行
that.resolvedCallbacks.map(cb => cb(that.value));
}
},0) }
function reject(value){
setTimeout(()=>{
if(that.state == PENDING){
that.state == REJECTED;
that.value = value;
that.rejectedCallbacks.map( cb => cb(that.value));
}
})
}
try {
fn(resolve, reject)
} catch (e) {
reject(e)
} }
MyPromise.prototype.then = function(onFulfilled, onRejected){
const that = this;
// 判断两个参数是否为函数类型, 这两个参数是可选参数
// 当参数不是函数类型时,需要创建一个函数赋值给对应的参数,同时也实现了透传
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : r => {throw r};
if(that.state === PENDING){
// 返回了一个新的 Promise 对象,并在 Promise 中传入了一个函数
// 规范规定,执行 onFulfilled 或者 onRejected 函数时会返回一个 x,并且执行 Promise 解决过程,这是为了不同的 Promise 都可以兼容使用,比如 JQuery 的 Promise 能兼容 ES6 的 Promise
return (promise2 = new MyPromise((resolve, reject)=>{
that.resolvedCallbacks.push(()=>{
try {
const x = onFulfilled(that.value)
resolutionProcedure(promise2, x, resolve, reject)
}catch (r) {
reject(r)
}
});
that.rejectedCallbacks.push(()=>{
try {
const x = onRejected(that.value)
resolutionProcedure(promise2, x, resolve, reject)
} catch (r) {
reject(r)
}
});
}))
}
if(that.state === RESOLVED){
return (promise2 = new MyPromise((resolve, reject)=>{
setTimeout(()=>{
try {
const x = onFulfilled(that.value)
resolutionProcedure(promise2, x, resolve, reject)
} catch (reason) {
reject(r)
}
})
}))
}
if(that.state === REJECTED){
return (promise2 = new MyPromise((resolve, reject)=>{
try {
const x = onRejected(that.value);
resolutionProcedure(promise2, x, resolve, reject)
}catch(r){
reject(r)
}
}))
} function resolutionProcedure(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Error'))
}
if (x instanceof MyPromise) {
x.then(function(value) {
resolutionProcedure(promise2, value, resolve, reject)
}, reject)
}
// 创建一个变量 用于判断是否已经调用过函数
// let called = false; // if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
// try {
// let then = x.then
// if (typeof then === 'function') {
// then.call(
// x,
// y => {
// if (called) return
// called = true
// resolutionProcedure(promise2, y, resolve, reject)
// },
// e => {
// if (called) return
// called = true
// reject(e)
// }
// )
// } else {
// resolve(x)
// }
// } catch (e) {
// if (called) return
// called = true
// reject(e)
// }
// } else {
// resolve(x)
// }
}
}
// 创建一个实例
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 0)
}).then(value => {
console.log(value)
})
手写符合Promise/A+规范的Promise的更多相关文章
- 手写一款符合Promise/A+规范的Promise
手写一款符合Promise/A+规范的Promise 长篇预警!有点长,可以选择性观看.如果对Promise源码不是很清楚,还是推荐从头看,相信你认真从头看到尾,并且去实际操作了,肯定会有收获的.主要 ...
- 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise
本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...
- 一步一步实现一个Promise A+规范的 Promise
2015年6月,ES2015(即ES6)正式发布后受到了非常多的关注.其中很重要的一点是 Promise 被列为了正式规范. 在此之前很多库都对异步编程/回调地狱实现了类 Promise 的应对方案, ...
- 手写基于Promise A+规范的Promise
const PENDING = 'pending';//初始态const FULFILLED = 'fulfilled';//初始态const REJECTED = 'rejected';//初始态f ...
- 手写promise
写在前面: 在目前的前端分开中,我们对于异步方法的使用越来越频繁,那么如果处理异步方法的返回结果,如果优雅的进行异步处理对于一个合格的前端开发者而言就显得尤为重要,其中在面试中被问道最多的就是对Pro ...
- 手写一个Promise/A+,完美通过官方872个测试用例
前段时间我用两篇文章深入讲解了异步的概念和Event Loop的底层原理,然后还讲了一种自己实现异步的发布订阅模式: setTimeout和setImmediate到底谁先执行,本文让你彻底理解Eve ...
- 手写 Promise
在上一章节中我们了解了 Promise 的一些易错点,在这一章节中,我们会通过手写一个符合 Promise/A+ 规范的 Promise 来深入理解它,并且手写 Promise 也是一道大厂常考题,在 ...
- 手写Promise看着一篇就足够了
目录 概要 博客思路 API的特性与手写源码 构造函数 then catch Promise.resolved Promise.rejected Promise.all Promise.race 概要 ...
- 按照 Promise/A+ 规范逐行注释并实现 Promise
0. 前言 面试官:「你写个 Promise 吧.」 我:「对不起,打扰了,再见!」 现在前端越来越卷,不会手写 Promise 都不好意思面试了(手动狗头.jpg).虽然没多少人会在业务中用自己实现 ...
随机推荐
- mysql DEFAULT约束 语法
mysql DEFAULT约束 语法 作用:用于向列中插入默认值. 说明:如果没有规定其他的值,那么会将默认值添加到所有的新记录.直线电机 mysql DEFAULT约束 示例 //在 "P ...
- luogu 2698 [USACO12MAR]花盆Flowerpot 单调队列
刷水~ Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in&quo ...
- layer.confirm
layer.confirm('确定不选择花车?', { title: false, btn: ['确定','取消'] //按钮 }, function(ind){ layer.close(ind); ...
- [CF535D]Tavas and Malekas 题解
题意简述 有一个空着的长度为\(n\)的字符串\(ans\),再给出一个长度为\(m\)的序列\(a\),现要在序列中每个元素\(a_i\)的位置开始都规定必须为一个给定的字符串\(s\).问字符串\ ...
- JS onclick中this用法
当在dom元素中使用onclick绑定事件的时候,可以使用this来指向该元素对象. 打印输出的内容为: 所以可以通过该this对象来获取子元素 //通过element获取该对象下的一个audio标签 ...
- 【BZOJ2200】道路和航线(并查集,拓扑排序,最短路)
题意:n个点,有m1条双向边,m2条单向边,双向边边长非负,单向边可能为负 保证如果有一条从x到y的单项边,则不可能存在从y到x的路径 问从S出发到其他所有点的最短路 n<=25000,n1,m ...
- #1126-JSP服务器响应
JSP服务器响应 Response响应对象主要将JSP容器处理后的结果传回到客户端.可以通过response变量设置HTTP的状态和向客户端发送数据,如Cookie.HTTP文件头信息等. 一个典型的 ...
- 动态DP总结
动态DP 何为动态DP? 将画风正常的DP加上修改操作. 举个例子? 给你一个长度为\(n\)的数列,从中选出一些数,要求选出的数互不相邻,最大化选出的数的和. 考虑DP,状态设计为\(f[i][1/ ...
- duration of lease 1 0.5 0.875 DHCP 租借时间 续租时间 重新绑定时间
w
- iptables List the rules in a chain or all chains
[root@e ~]# iptables -hiptables v1.4.21 Usage: iptables -[ACD] chain rule-specification [options] ip ...