/** * 判断then方法传入的参数是否是方法 * @param value 这里把then的参数传入 * @returns {boolean} */const isFunction = (value) => typeof value === 'function';class MyPromise { constructor(executor) { this.state = 'pending';//设置实例对象的state状态,默认是pedding this.value = undefined;//储存resolve回调函数的value的值,的数据 this.reason = undefined;//储存reject的回调函数的reason的数据 this.onFullFilledCallbacks = [];//储存异步操作成功的回调函数 this.onRejectedCallbacks = [];//储存异步操作失败的回调函数 //设置成功回调函数 let resolve = (value) => { this.state = 'fullFilled'; this.value = value; /*当回调函数运行时,运行储存在数组中函数*/ this.onFullFilledCallbacks.forEach(fn => fn()); } /*失败回调函数*/ let reject = (reason) => { this.state = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()); } // executor(resolve, reject); /*try catch捕获异常,失败需要走reject*/ try { executor(resolve, reject); } catch (err) { reject(err) } } /** *then方法 * @param onFullFilled 成功的回调 * @param onRejected 失败的回调 * @returns {MyPromise} 返回值是promise对象 */ then(onFullFilled, onRejected) { /*判断是否是方法,是方法就返回方法,不是方法,就组装成方法*/ onFullFilled = isFunction(onFullFilled) ? onFullFilled : data => data; /*是方法返回方法,不是方法抛出错误*/ onRejected = isFunction(onRejected) ? onRejected : err => { throw err; }; /** * 新建新的mypromie,用于返回,这是为了能够可以链式调用 * @type {MyPromise} */ const p2 = new MyPromise((resolve, reject) => { let x; if (this.state === 'fullFilled') { /*让resolvePromise(p2, x, resolve, reject);之后再运行,因为让resolvePromise调用p2时,p2并没有没有生成*/ setTimeout(() => { /*当异常时通过reject抛出异常*/ try { x = onFullFilled(this.value); // console.log(172, x); resolvePromise(p2, x, resolve, reject); } catch (err) { reject(err) } }, 0) /* x = onFullFilled(this.value); // console.log('165:'+x) // resolve(x); resolvePromise(p2, x, resolve, reject)*/ } if (this.state === 'rejected') { setTimeout(() => { try { x = onRejected(this.reason); resolvePromise(p2, x, resolve, reject); } catch (err) { reject(err) } }, 0) } if (this.state === 'pending') { /* this.onFullFilledCallbacks.push(onFullFilled); this.onRejectedCallbacks.push(onRejected);*/ /*存入成功的回调函数,观察者模式,先记录需要观察什么东西*/ this.onFullFilledCallbacks.push(() => { setTimeout(() => { try { x = onFullFilled(this.value); resolvePromise(p2, x, resolve, reject); } catch (err) { reject(err) } }, 0) }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { x = onRejected(this.reason); resolvePromise(p2, x, resolve, reject); } catch (err) { reject(err) } }, 0) /* x = onRejected(this.reason); // resolve(x); resolvePromise(p2, x, resolve, reject);*/ }); } }) return p2; }}/** * 因为promise规范规定 x不能等于p2 * @param p2 then运行的返回值,promise * @param x 成功失败函数运行返回的值,回调函数传入实参运行返回的值 * @param resolve 成功回调 * @param reject 失败回调 */function resolvePromise(p2, x, resolve, reject) { // console.log(192, p2, x, resolve, reject); // console.log(209,a); //为了让回调函数执行一次上一把锁 let called; if (p2 === x) { reject(new TypeError('typeErr')); } /*x可以是个方法,再return出去一个值*/ if ((typeof x === 'object' && x != null) || x === 'function') { try { /*thenable对象,这是处理return new Promise的情况*/ let then = x.then; if (typeof then === 'function') { /* then.call(x是让then需要上下文,让then的上下文,变成x,变成 * 返回的promise,相当于返回的promise.then*/ then.call(x, y => { /*x.then值是一样的*/ // x.then(y => { /*这时then独立调用指向window*/ // then(y=>{ /*true时,走return直接终止函数运行,终止resolvePromise的运行,不是mypromise的运行*/ if (called) return; called = true; console.log(250, y); resolve(y); }, r => { if (called) return; called = true; console.log(252, r); reject(r); }) } else { if (called) return; called = true; resolve(x); } } catch (err) { if (called) return; called = true; reject(err); } } else { /*这里不需要锁了*/ resolve(x); }}/*/!*换成mypromise*!/// const p1 = new Promise((resolve, reject) => {const p1 = new MyPromise((resolve, reject) => { // setTimeout(() => { resolve(1); // reject(1); // }, 1000)})const p2 = p1.then((res) => { // console.log(res); // return res + 1; /!*返回值是一个Promise,想要拿到里面的reject,怎么拿到,需要通过得到它xx, * xx.then的方式得到10*!/ return new MyPromise((resolve, reject) => { reject(10); })}, err => { // console.log(err) return err + 2;})p2.then(res => { console.log(266, res, 'success');}, err => { console.log(268, err, 'error');})*//*3 success*/MyPromise.defer = MyPromise.deferred = function () { let dfd = {}; dfd.promise = new MyPromise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }) return dfd;}module.exports = MyPromise;