参考地址:地址。
目录
二,实现executor执行器,完善resolve和reject函数
三,实现throw抛出异常后置PromiseState = 'no'
五,实现then方法对resolved,rejected状态的支持
八,实现then返回一个Promise对象(由同步任务决定状态)
一,搭建整体框架和添加then方法到Promise原型
function myPromise(executor) {
}
myPromise.prototype.then(solved, rejectd);
二,实现executor执行器,完善resolve和reject函数
function myPromise(executor) {
//令executor === (f = (resolve, reject) => resolve('ok'));用于测试的操作,省去了异步操作,resolve, reject函数选择resolve执行
/*置初始状态*/
this.PromiseState = 'waiting';
/*置初始结果*/
this.PromiseResult = null;
/*让ins指向实例对象*/
const ins = this;
/*实现resolve函数,将异步操作的结果给PromiseResult*/
function resolve(data) {
/*改变实例对象的状态*/
ins.PromiseState = 'yes';
ins.PromiseResult = data;
};
/*实现reject函数*/
function reject(data) {
ins.PromiseState = 'no';
ins.PromiseResult = data;
};
/*同步调用执行器,执行传进来的任务,executor被主线程执行后将异步操作放入事件队列*/
executor(resolve, reject);
//在这里声明resolve, reject这两个变量,根据业务逻辑选择必须resolve, reject二选一执行,将结果交给resolve, reject即可。
}
myPromise.prototype.then = function(onresolved, onrejectd) {
};
};
三,实现throw抛出异常后置PromiseState = 'no'
我这个例子写的是no,官方的是rejected。因为只有executor执行出了问题才会异常(貌似只有executor可以执行),所以将executor放入trycatch中。
//单独的解决方法
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
四,完善PromiseState只能被修改一次
解决方法如下:
function resolve(data) {
/*改变实例对象的状态*/
if (ins.PromiseState == 'waiting') {
ins.PromiseState = 'yes';
}
ins.PromiseResult = data;
};
/*实现reject函数*/
function reject(data) {
if (ins.PromiseState == 'waiting') {
ins.PromiseState = 'no';
}
ins.PromiseResult = data;
};
五,实现then方法对resolved,rejected状态的支持
实现方法如下。本例使用yes和no代替。
myPromise.prototype.then = function(onresolved, onrejectd) {
if (this.PromiseState == 'yes') {
onresolved(this.PromiseResult); //将实例对象的结果传给回调函数进行处理
}
if (this.PromiseState == 'no') {
onrejectd(this.PromiseResult);
}
};
六,实现then方法对pending状态的支持
本例以waiting为例。处于pending的状态大都是因为执行器中放了一个耗时的异步操作,一直没有调用resolve, reject这两个函数,导致状态一直为pending。
但是then方法的作为参数的两个回调方法只能处理resolved和rejected状态。而且then方法不可能给pending状态添加回调函数,因为对pending状态进行处理会让主线程挂起,这是不可行的。
另外,如果主线程在还是pending状态时就执行到then方法,会将then方法丢进事件队列(微任务队列),然后接着运行下面的代码,在这之后如果状态改变该如何处理需要被解决。
解决方法就是:将resolved和rejected状态对应的回调函数进行保存,等到状态变化之后再执行。
function myPromise(executor) {
//令executor === (f = (resolve, reject) => resolve('ok'));用于测试的操作,省去了异步操作,resolve, reject函数选择resolve执行
/*置初始状态*/
this.PromiseState = 'waiting';
/*置初始结果*/
this.PromiseResult = null;
/*让ins指向实例对象*/
const ins = this;
/*保存当前实例对象的两个回调函数*/
ins.callback = {};
/*实现resolve函数,将异步操作的结果给PromiseResult*/
function resolve(data) {
/*改变实例对象的状态*/
if (ins.PromiseState == 'waiting') {
ins.PromiseState = 'yes';
}
ins.PromiseResult = data;
/*对是否为waiting状态进行判断,如果主线程经过then的时候还是waiting,则具有solved,rejected两个属性*/
if (ins.callback.solved) {
ins.callback.solved(data);
}
};
/*实现reject函数*/
function reject(data) {
if (ins.PromiseState == 'waiting') {
ins.PromiseState = 'no';
}
ins.PromiseResult = data;
/*对是否为waiting状态进行判断,如果主线程经过then的时候还是waiting,则具有solved,rejected两个属性*/
if (ins.callback.rejected) {
ins.callback.rejected(data);
}
};
/*同步调用执行器,执行传进来的任务,executor被主线程执行后将异步操作放入事件队列*/
try {
//在这里声明resolve, reject这两个变量,根据业务逻辑选择必须resolve, reject二选一执行,将结果交给resolve, reject即可。
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
myPromise.prototype.then = function(solved, rejected) {
//solved, rejected分别对应成功和失败的回调函数。
if (this.PromiseState == 'yes') {
solved(this.PromiseResult); //将实例对象的结果传给回调函数进行处理
}
if (this.PromiseState == 'no') {
rejected(this.PromiseResult);
}
//当主线程执行到then方法的时候还是pending状态的话就将两个回调函数保存,主线程放弃了他们,程序员不能
if (this.PromiseState == 'waiting') {
this.callbacks = {
solved,
rejected
}
}
};
七,实现then绑定多个回调函数
多次给then绑定不同的回调函数,会丢失对前面的联系,只会绑定到最后一次的回调函数。当多次使用:p.then时,把这些回调函数都保存起来,然后依次调用即可。
function myPromise(executor) {
//令executor === (f = (resolve, reject) => resolve('ok'));用于测试的操作,省去了异步操作,resolve, reject函数选择resolve执行
/*置初始状态*/
this.PromiseState = 'waiting';
/*置初始结果*/
this.PromiseResult = null;
/*让ins指向实例对象*/
const ins = this;
/*保存当前实例对象的两个回调函数*/
ins.callbacks = [];
/*实现resolve函数,将异步操作的结果给PromiseResult*/
function resolve(data) {
/*改变实例对象的状态*/
if (ins.PromiseState == 'waiting') {
ins.PromiseState = 'yes';
}
ins.PromiseResult = data;
/*对多个then传进来的回调函数依次执行*/
ins.callbacks.forEach((item) => item.solved(data))
};
/*实现reject函数*/
function reject(data) {
if (ins.PromiseState == 'waiting') {
ins.PromiseState = 'no';
}
ins.PromiseResult = data;
/*对多个then传进来的回调函数依次执行*/
ins.callbacks.forEach((item) => item.rejected(data))
};
/*同步调用执行器,执行传进来的任务,executor被主线程执行后将异步操作放入事件队列*/
try {
//在这里声明resolve, reject这两个变量,根据业务逻辑选择必须resolve, reject二选一执行,将结果交给resolve, reject即可。
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
myPromise.prototype.then = function(solved, rejected) {
//solved, rejected分别对应成功和失败的回调函数。
if (this.PromiseState == 'yes') {
solved(this.PromiseResult); //将实例对象的结果传给回调函数进行处理
}
if (this.PromiseState == 'no') {
rejected(this.PromiseResult);
}
//当主线程执行到then方法的时候还是pending状态的话就将两个回调函数保存,主线程放弃了他们,程序员不能
if (this.PromiseState == 'waiting') {
this.callbacks.push({
solved,
rejected
});
}
};
八,实现then返回一个Promise对象(由同步任务决定状态)
由原生Promise类可知,then方法返回一个Promise对象,且返回结果由回调函数的执行结果决定。如下图。
function myPromise(executor) {
//令executor === (f = (resolve, reject) => resolve('ok'));用于测试的操作,省去了异步操作,resolve, reject函数选择resolve执行
/*置初始状态*/
this.PromiseState = 'waiting';
/*置初始结果*/
this.PromiseResult = null;
/*让ins指向实例对象*/
const ins = this;
/*保存当前实例对象的两个回调函数*/
ins.callbacks = [];
/*实现resolve函数,将异步操作的结果给PromiseResult*/
function resolve(data) {
/*改变实例对象的状态*/
if (ins.PromiseState == 'waiting') {
ins.PromiseState = 'yes';
}
ins.PromiseResult = data;
/*对多个then传进来的回调函数依次执行*/
ins.callbacks.forEach((item) => item.solved(data))
};
/*实现reject函数*/
function reject(data) {
if (ins.PromiseState == 'waiting') {
ins.PromiseState = 'no';
}
ins.PromiseResult = data;
/*对多个then传进来的回调函数依次执行*/
ins.callbacks.forEach((item) => item.rejected(data))
};
/*同步调用执行器,执行传进来的任务,executor被主线程执行后将异步操作放入事件队列*/
try {
//在这里声明resolve, reject这两个变量,根据业务逻辑选择必须resolve, reject二选一执行,将结果交给resolve, reject即可。
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
myPromise.prototype.then = function(solved, rejected) {
task = (resolve, reject) => {
if (this.PromiseState == 'yes') {
//成功状态下记录结果,根据结果决定执行resolve还是reject
let result = solved(this.PromiseResult);
try {
if (result instanceof myPromise) {
//假如是myPromise还需要细分
result.then(
v => { resolve(v) },
err => { reject(err) }
)
} else {
//不是mypromise的实例,则直接使用resolve函数返回result
resolve(result);
}
} catch (error) {
reject(error);
}
}
if (this.PromiseState == 'no') {
rejected(this.PromiseResult);
}
if (this.PromiseState == 'waiting') {
this.callbacks.push({
solved,
rejected
});
}
}
return new myPromise(task); //then方法需要返回一个myPromise实例,在这里返回
}