手写promise 对promise更详细的理解
作者:互联网
首先还是上应用层的promise代码
以便对结构的理解
let remember = true;
let getMoney = new Promise((resolve,reject)=>{
if(remember){
let money = 999
resolve(money)
}else{
let noMoney = new Error('今年你已经毕业了,没有红包了');
reject(noMoney)
}
})
let test = function(){
getMoney.then((fulfilled)=>{
console.log(fulfilled);
}).catch((rejected)=>{
console.log(rejected.message);
})
}
test()
基本结构
这里我们可以看出 一个promise实例
我们需要 知道他的状态 一开始为panding 待处理状态
如果成功 返回一个值
如果失败 返回错误原因
由应用层代码来看
需要一个处理成功的方法resolve 和 处理失败的方法reject
还有一个.then的方法(.catch方法实质上就是.then方法的另一种写法 搭架子时候暂时忽略)
我们每构造一个新promise实例 都要用到then方法 那么我们把then写在我们自己构造的promise原型中 构造函数可以继承使用
理清逻辑 架子为
function myPromise(){
let self = this; //接收当前内容
self.status = 'pending'; //状态
self.value = null; //成功之后,返回的数据
self.reason = null; //失败了,失败的原因
//返回成功的结果
function resolve(){
}
//返回失败的原因
function reject(){
}
}
//2.then()
myPromise.prototype.then = function(){
}
//3.初级调用
let demo = new myPromise((resolve,reject)=>{
console.log("111");
})
当然到了这里 这个111是打印不出来的 显而易见 没有调用
function myPromise(excutor){
let selt = this; //接收当前内容
self.status = 'pending'; //状态
self.value = null; //成功之后,返回的数据
self.reason = null; //失败了,失败的原因
//返回成功的结果
function resolve(){
}
//返回失败的原因
function reject(){
}
try {
excutor(resolve,reject)
} catch (error) {
reject(error)
}
}
所以我们补全代码 传入一个执行器excutor 执行器方法也是调用resolve reject
当我们运用new Promise时候传两个参数 resolve reject 这效果是一样的 同步立即执行
之后进行进一步的完善
function resolve(value){
//5.1
if(self.status === 'pending'){
self.value = value //保存成功的结果
self.status = 'fulfilled' //状态更改
}
}
//返回失败的原因
function reject(reason){
//5.2
if(self.status === 'pending'){
self.reason = reason //失败原因
self.status = 'rejected' //状态更改
}
}
初始状态肯定为pending待处理 然后开始完善resolve 和 reject方法
成功即保存结果 失败即抛出原因
当然此时的状态也要随之改变为fulfilled或者rejected
无论成功与否 下面就要进入到then方法里
//6.确保传进来的是方法 如果不是的话 定义一个方法
myFulfilled = typeof myFulfilled === 'function' ?
myFulfilled : function(data) { resolve(data) }
myRejceted = typeof myRejected === 'function' ?
myRejected : function(err) { throw err }
then方法写完 就要开始实现如何实现异步操作 Promise是一个比较好的异步操作方法 当然异步也要考虑进去
//7.暂存区
self.fulfilledBack = [];
self.rejectBack = [];
先定义一个暂存区 这个暂存也是在then方法里存
因为由应用层代码可以看出 promise实例进行.then方法之后 才可执行相应操作
let self = this;
if(self.status === 'pending'){
self.fulfilledBack.push(myFulfilled);
self.rejectedBack.push(myReject);
}
暂存之后的数据 要取出 当成功时候 在resolve取出 失败时候 在reject取出
function resolve(value){
//5.1
if(self.status === 'pending'){
self.value = value //保存成功的结果
self.status = 'fulfilled' //状态更改
//9.状态发生改变 => 依次取出
self.fulfilledBack.forEach(item => item(value))
}
}
//返回失败的原因
function reject(reason){
//5.2
if(self.status === 'pending'){
self.reason = reason //失败原因
self.status = 'rejected' //状态更改
self.rejectedBack.forEach(item => item(reason))
}
}
这样继续完善resolve方法 和 reject 方法
到这里就算是结束了
如果有需要 我把整个代码放过来 自提
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手写promise</title>
</head>
<body>
<h2>手写promise</h2>
<script>
function myPromise(excutor){
let self = this; //接收当前内容
self.status = 'pending'; //状态
self.value = null; //成功之后,返回的数据
self.reason = null; //失败了,失败的原因
//7.暂存区
self.fulfilledBack = [];
self.rejectedBack = [];
//返回成功的结果
function resolve(value){
//5.1
if(self.status === 'pending'){
self.value = value //保存成功的结果
self.status = 'fulfilled' //状态更改
//9.状态发生改变 => 依次取出
self.fulfilledBack.forEach(item => item(value))
}
}
//返回失败的原因
function reject(reason){
//5.2
if(self.status === 'pending'){
self.reason = reason //失败原因
self.status = 'rejected' //状态更改
self.rejectedBack.forEach(item => item(reason))
}
}
//4.excutor =>立即执行
try {
excutor(resolve,reject)
} catch (err) {
reject(err)
}
}
//2.then()
myPromise.prototype.then = function(myFulfilled,myRejected){
//6.确保传进来的是方法 如果不是的话 定义一个方法
myFulfilled = typeof myFulfilled === 'function' ?
myFulfilled : function(data) { resolve(data) }
myRejected = typeof myRejected === 'function' ?
myRejected : function(err) { throw err }
let self = this;
//8.暂存回调函数
if(self.status === 'pending'){
self.fulfilledBack.push(myFulfilled);
self.rejectedBack.push(myRejected);
}
}
//3.初级调用
let demo = new myPromise((resolve,reject)=>{
console.log("111")
setTimeout(() => {
resolve(222)
}, 2000);
})
//console.log(demo);
let test = function() {
demo.then((data)=>{
console.log(data)
})
}
test()
</script>
</body>
</html>
如果对手写的原理层代码感觉有问题 可以对照这个应用层代码 代码在文章最开始有 这是对应用层代码的解释
https://blog.csdn.net/qq_45158336/article/details/122782823
标签:function,status,resolve,self,reason,promise,详细,reject,手写 来源: https://blog.csdn.net/qq_45158336/article/details/122783169