手写 Promise
1、初始结构搭建
//搭建Promise的构造函数
function Promise(executor) {
//executor为执行器函数
}
//在Promise原型上添加.then()方法
Promise.prototype.then = function (onResolve, onReject) {};
2、指定 Promise 构造函数的 resolve 和 reject 方法
function Promise(executor) {
//Promise同步调用执行器函数,
//构造函数内直接进行调用,并传入resolve和reject
ececutor(resolve, reject);
}
Promise.prototype.then = function (onResolve, onReject) {};
3、定义 resolve 和 reject 方法定义
function Promise(executor) {
//声明resolve方法
function resolve(data) {
//设置data形参,用于接收成功结果
}
//声明reject方法
function reject(data) {
//设置data形参,用于接收失败结果
}
//调用执行器函数
executor(resolve, reject);
}
Promise.prototype.then = function (onResolve, onReject) {};
4、处理 resolve 和 reject 的内部实现
function Promise(executor) {
// 添加Promise状态属性
this.PromiseState = "pending";
// 添加Promise结果属性
this.PromiseResult = null;
// 保存实例的this指向
const _this = this;
function resolve(data) {
//1.修改对象的状态 (promiseState)
_this.PromiseState = "fulfilled";
//2.设置对象结果值(promiseResult)
_this.PromiseResult = data;
}
function reject(data) {
//1.修改对象的状态 (promiseState)
_this.PromiseState = "rejected";
//2.设置对象结果值(promiseResult)
_this.PromiseResult = data;
}
executor(resolve, reject);
}
Promise.prototype.then = function (onResolve, onReject) {};
5、增加 throw 抛出异常修改状态
function Promise(executor) {
this.PromiseState = "pending";
this.PromiseResult = null;
const _this = this;
function resolve(data) {
_this.PromiseState = "fulfilled";
_this.PromiseResult = data;
}
function reject(data) {
_this.PromiseState = "rejected";
_this.PromiseResult = data;
}
//使用try...catch...捕获错误
try {
executor(resolve, reject);
} catch (e) {
//调用reject方法修改状态及值
reject(e);
}
}
Promise.prototype.then = function (onResolve, onReject) {};
6、使 Promise 的状态只能修改一次,且不可再次更改
function Promise(executor){
this.PromiseState = 'pending'
this.PromiseResult = null
const _this = this
function resolve(data){
//判断PromiseState是否被修改
if(_this.PromiseState !== 'pending'{
return
}
_this.PromiseState = 'fulfilled'
_this.PromiseResult = data
}
function reject(data){
//判断PromiseState是否被修改
if(_this.PromiseState !== 'pending'{
return
}
_this.PromiseState = 'rejected'
_this.PromiseResult = data
}
try{
executor(resolve,reject)
} catch(e){
reject(e)
}
}
Promise.prototype.then = function(onResolve,onReject){}
.then()
的功能实现
7、实现Primise.prototype.then = function (onResolve, onReject) {
//判断当前Promise的状态为成功时
if (this.PromiseState === "fulfilled") {
//调用外部定义好的onResolve函数,并传递结果值
onResolve(this.PromiseResult);
}
//判断当前Promise的状态为失败时
if (this.PromiseState === "rejected") {
//调用外部定义好的onReject函数,并传递失败值
onReject(this.PromiseResult);
}
};
8、异步任务处理的实现
程序执行过程中按同步顺序执行,当执行器函数中包含异步任务时,顺序按下执行
.then()
位置,此时 Promise 状态未进行变更,判断无法命中,去进行 onResolve 或者 onReject 方法的调用
Primise.prototype.then = function (onResolve, onReject) {
if (this.PromiseState === "fulfilled") {
onResolve(this.PromiseResult);
}
if (this.PromiseState === "rejected") {
onReject(this.PromiseResult);
}
//判断 pending 状态
if (this.PromiseState === "pending") {
//将onResolve 和 onReject 进行自身保存
this.callback = {
onResolve: onResolve,
onReject: onReject,
};
}
};
在 Promise 内部进行了状态变更时,调用回调函数
//修改Promise函数内部实现
function Promise(executor){
this.PromiseState = 'pending'
this.PromiseResult = null
const _this = this
//新增回调属性,用于保存回调函数
this.callback = {}
function resolve(data){
if(_this.PromiseState !== 'pending'{
return
}
_this.PromiseState = 'fulfilled'
_this.PromiseResult = data
//状态修改后,进行回调函数的调用
if(_this.callback.onResolve){
//调用回调函数,并传递参数
_this.callback.onResolve(data)
}
}
function reject(data){
if(_this.PromiseState !== 'pending'{
return
}
_this.PromiseState = 'rejected'
_this.PromiseResult = data
//状态变为失败后,进行失败回调的调用
if(_this.callback.onReject){
//调用回调函数,并传递参数
_this.callback.onReject(data)
}
}
try{
executor(resolve,reject)
} catch(e){
reject(e)
}
}
9、指定多个回调,并在状态修改后依次调用
修改 callback 的保存方式
Primise.prototype.then = function (onResolve, onReject) {
if (this.PromiseState === "fulfilled") {
onResolve(this.PromiseResult);
}
if (this.PromiseState === "rejected") {
onReject(this.PromiseResult);
}
if (this.PromiseState === "pending") {
//将回调以数组形式进行压栈
this.callback.push({
onResolve: onResolve,
onReject: onReject,
});
}
};
//修改callback的保存、调用方式
function Promise(executor){
this.PromiseState = 'pending'
this.PromiseResult = null
const _this = this
//使用数组形式保存回调函数
this.callback = [ ]
function resolve(data){
if(_this.PromiseState !== 'pending'{
return
}
_this.PromiseState = 'fulfilled'
_this.PromiseResult = data
//修改callback的调用方式,遍历循环依次调用
_this.callback.forEach(item=>{
item.onResolve(data)
})
}
function reject(data){
if(_this.PromiseState !== 'pending'{
return
}
_this.PromiseState = 'rejected'
_this.PromiseResult = data
//修改callback的调用方式,遍历循环依次调用
_this.callback.forEach(item=>{
item.onReject(data)
})
}
try{
executor(resolve,reject)
} catch(e){
reject(e)
}
}
.then()
的返回结果
10、同步状态下
.then()
的返回结果根据.then()
内部返回值确定1、返回结果是非 Promise,状态为成功
2、返回是 Promise,根据这个 Promise 状态确定状态
3、返回是错误或者抛出错误,状态为失败
//修改.then()方法返回值
Primise.prototype.then = function(onResolve,onReject){
//.then() 方法返回一个 Promise 实例
return new Promise((resolve,reject)=>{
//使用try...catch...对异常进行捕获,第三种情况
try{
if(this.PromiseState === 'fulfilled'){
//获取回调函数的执行结果
//onResolve 为普通函数,
//未进行返回时,默认返回undefined
let result = onResolve(this.PromiseResult)
//判断 onResolve 返回结果是否为 Promise 类型
if(result instanceOf Promise){
//Promise 类型
result.then(value=>{
//返回的 Promise 成功时
//调用.then方法返回的那个 Promise 实例的 resolve 方法,修改返回的 Promise 状态及结果
resolve(value)
},reason=>{
//返回的 Promise 失败时
//调用.then方法返回的 Promise 实例的 reject 方法,修改返回的 Promise 状态及结果
reject(reason)
})
}else{
//非 Promise 类型,调用上面的 resolve 方法
resolve(result)
}
} catch(e){
//调用返回的 Promise 实例的 reject 方法,将状态及结果修改为失败
reject(e)
}
}
if(this.PromiseState === 'rejected'){
onReject(this.PromiseResult)
}
if(this.PromiseState === 'pending'){
//将回调以数组形式进行压栈
this.callback.push({
onResolve: onResolve,
onReject: onReject
})
}
})
}
.then()
的返回结果
11、处理异步任务当初始的 Promise 处理器函数内包含异步任务时,在
.then()
内部会命中this.PromiseState === 'pending'
,而此时这个内部的处理中没有对.then()
返回的那个 Promise 进行状态处理
问题出现位置如下:
if (this.PromiseState === "pending") {
//将回调以数组形式进行压栈
this.callback.push({
onResolve: onResolve,
onReject: onReject,
});
}
//此时.then()返回的 Promise 状态为pending 且不会被修改
处理方式:( 处理的大致步骤与上一步骤相同 )
if(this.PromiseState === 'pending'){
this.callback.push({
//对 onResolve 回调函数进行一个封装
onResolve: ()=>{
//使用try...catch...捕获错误
try{
//执行成功回调函数,并接收返回的结果
let result = onResolve(this.PromiseResult)
//判断返回值是否为Promise
if(result instanceOf Promise){
//返回的为Promise 类型
result.then(value=>{
//返回的Promise 成功时,调用.then() 返回的Promise 的 resolve 方法修改状态及结果
resolve(value)
},reason=>{
//返回的Promise 失败时,调用.then() 返回的Promise 的 reject 方法修改状态及结果
reject(reason)
})
}else{
//普通数据类型,调用.then()返回的Promise 的resolve 方法修改状态及结果
resolve(result)
}
}catch(e){
//捕获到错误时,调用.then() 返回的 Promise 的reject方法 修改状态及结果
reject(e)
}
} ,
onReject: ()=>{
onReject(this.PromiseResult)
}
})
}