参考:
1.https://www.jianshu.com/p/f841eb3c1006
2.https://blog.csdn.net/qq_31967985/article/details/109902310
阶段一:只支持链式调用不支持其他api
// 定义promise中的三种状态 const STATUS_PENDING = "pending"; const STATUS_FULFILLED = "fulfilled"; const STATUS_REJECTED = "rejected"; // 定义promise的类 class myPromise { //class的构造函数,接受新建实例时的参数:executor在promise中是一个函数 constructor(executor) { //初始化该class中的初始状态 this.status = STATUS_PENDING; //定义class中成功(res)和失败(err)时的变量值 this.res = ""; this.err = ""; //promis异步中最重要的异步,定义成功和错误函数存储的数组,存放异步时还没有执行的操作 this.onResCallbacks = []; this.onErrCallbacks = []; //按照promise中的逻辑,在调用时就立即执行了,所以在手写的myPromise创建构造函数constructor时就执行executor try { //执行参入的函数,并将上述定义的resolve和reject作为参数传入 executor(this.resolve.bind(this), this.reject.bind(this)) // 绑定当前实例 } catch (err) { //报错时调用失败的状态函数 reject(err); } } resolve(res){ // 首先判断该class中的状态,只有状态为pending时才能转化class转态为fulfilled或者rejected this.status === STATUS_PENDING && ( //修改class的转态为fulfilled,也就表示不会转进行其他转态的转化了 this.status = STATUS_FULFILLED, //将成功(resolve)状态下的值赋给class的成功返回res this.res = res, //此时状态由pending转为fulfilled,执行之前在then中存放的需要执行的异步操作,promise的then中参数res接受结果 this.onResCallbacks.forEach((fn)=>fn()) ) return this; } //定义该构造函数constructor定义域中的变量reject reject(err){ // 首先判断该class中的状态,只有状态为pending时才能转化class转态为fulfilled或者rejected this.status === STATUS_PENDING && ( //修改class的转态为rejected,也就表示不会转进行其他转态的转化了 this.status = STATUS_REJECTED, this.err = err, //此时状态由pending转为rejected,执行之前在catch中存放的需要执行的异步操作,promise的catch中参数err接受结果 this.onErrCallbacks.forEach((fn)=>fn()) ) return this; } resolvePromise(x,resolve, reject) { // 如果返回的是myPromise实例 if (x instanceof myPromise) { x.then( data => { resolve(data) }, error => { reject(error) } ) } else { // 普通值:直接执行then返回的新promise方法的resolve,后一个then属于这个实例的,订阅队列也是属于这个实例的 resolve(x) } } //在class中定义promise的成功状态接收函数then,按照promise逻辑,then中传入的一般都是一个函数 then(success, fail){ // 链式调用 后一个then调用前一个then返回的promise实例 let p = new myPromise((resolve, reject) => { if (this.status === STATUS_PENDING) { // promise实例还在pending状态调用了then方法,增加订阅者 if (success && typeof success === 'function') { this.onResCallbacks.push(() => { try { // 用户调用then方法,callback函数,两种情况 // 1 非promise对象: return 什么就作为参数传递给下个then什么 // 2 promise对象:择要等用户的promise的有结果才执行下一个函数 let x = success(this.res) // 统一封装到一个函数中处理 this.resolvePromise(x, resolve, reject) } catch (e) { reject(e) } }) } if (fail && typeof fail === 'function') { this.onErrCallbacks.push(() => { try { let x = fail(this.err) this.resolvePromise(x, resolve, reject) } catch (e) { reject(e) } }) } } else if (this.status === STATUS_FULFILLED) { try { let x = success(this.res) this.resolvePromise(x, resolve, reject) } catch (e) { reject(e) } } else if(this._status === STATUS_REJECTED) { try { let x = fail(this.err) this.resolvePromise(x, resolve, reject) } catch (e) { reject(e) } } }) return p } //在class中定义promise的失败状态接收函数catch,按照promise逻辑,catch中传入的一般都是一个函数 catch(onErr = () => {}) { //如果是异步的,此时在constructor中status的状态还没变成rejected,所以会跳过onErr调用,没有返回 if (this.status === STATUS_REJECTED) { onErr(this.err); } //但是我们将此时的异步放入数组存放 if (this.status === STATUS_PENDING) { this.onErrCallbacks.push(() => onErr(this.err)); } //这步操作保证了then和catch能够在同级一起"."调起,当catch上述操作完后,返回class实例,便可以接在后面继续调用then return this; } } let my = new myPromise(()=>{}); new myPromise(function (resolve, reject) { console.log(00000) setTimeout(() => { resolve(222); console.log(111) }, 1000); }).then(function (res) { console.log('2 then') console.log(res) return my.resolve("hello world3333") }).then(function (res) { console.log(res); console.log('last then') });
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。