参考地址:地址。
目录
二,实现executor执行器,完善resolve和reject函数
三,实现throw抛出异常后置PromiseState = 'no'
五,实现then方法对resolved,rejected状态的支持
八,实现then返回一个Promise对象(由同步任务决定状态)
- function myPromise(executor) {
-
- }
- myPromise.prototype.then(solved, rejectd);
- 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) {
-
- };
-
- };
我这个例子写的是no,官方的是rejected。因为只有executor执行出了问题才会异常(貌似只有executor可以执行),所以将executor放入trycatch中。
- //单独的解决方法
- try {
- executor(resolve, reject);
- } catch (error) {
- reject(error);
- }
解决方法如下:
- 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;
- };
实现方法如下。本例使用yes和no代替。
- myPromise.prototype.then = function(onresolved, onrejectd) {
- if (this.PromiseState == 'yes') {
- onresolved(this.PromiseResult); //将实例对象的结果传给回调函数进行处理
- }
- if (this.PromiseState == 'no') {
- onrejectd(this.PromiseResult);
- }
- };
本例以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绑定不同的回调函数,会丢失对前面的联系,只会绑定到最后一次的回调函数。当多次使用: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
- });
- }
-
-
- };
由原生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实例,在这里返回
- }