一、Promise源码重写
-
基本功能
class MyPromise { // new的时候传入executor函数 constructor(executor) { this.state = 'pending'; // 提供状态、成功返回值与失败返回值 this.value = undefined; this.reason = undefined; let resovle = (value) => { // 定义resolve函数 this.state = 'fullFilled'; this.value = value; } let reject = (reason) => { // 定义reject函数 this.state = 'reject'; this.reason = reason; } executor(resovle, reject); // 提供resolve和reject两个函数 } then(onFullFilled, onRejected) { // 定义then方法,接收成功与失败的回调函数 if (this.state === 'fullFilled') { // 如果状态为成功,则返回成功的返回值,通过形参传给回调函数 onFullFilled(this.value); } if (this.state === 'rejected') { // 如果状态为失败,则返回失败的返回值,通过形参传给回调函数 onRejected(this.reason); } } } const p1 = new MyPromise((resolve, reject) => { resolve(1); }); p1.then((res) => { console.log(res); }, (err) => { console.log(err); }); // 输出1
-
处理异步任务、绑定多个回调
executor执行的时候,resolve并没有执行,1秒钟后resolve才执行
所以说在new MyPromise的时候,MyPromise的状态还是pennding,此时就可以认定是在处理异步任务
class MyPromise { constructor(executor) { this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onFullFilledCallbacks = []; // 当多次绑定回调,则将其存入对应的成功/失败数组中遍历执行 this.onRejectedCallbacks = []; let resovle = (value) => { this.state = 'fullFilled'; this.value = value; this.onFullFilledCallbacks.forEach(fn => fn()); // 这里可以传参fn(this.value),但是并不好,应该在then中统一处理参数 } let reject = (reason) => { this.state = 'reject'; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()); // fn(this.reason) } executor(resovle, reject); } then(onFullFilled, onRejected) { // 同步情况 if (this.state === 'fullFilled') { onFullFilled(this.value); } if (this.state === 'rejected') { onRejected(this.reason); } // 异步情况 if (this.state === 'pending') { // 用函数包装一次,有点像代理模式 this.onFullFilledCallbacks.push(() => { onFullFilled(this.value); }); this.onRejectedCallbacks.push(() => { onRejected(this.reason); }); } } } const p1 = new MyPromise((resolve, reject) => { setTimeout(() => { resolve(1); // executor执行的时候,resolve并没有执行,1秒钟后resolve才执行 }, 1000) }); p1.then((res) => { console.log(res); }, (err) => { console.log(err); }); p1.then((res) => { console.log(res); }, (err) => { console.log(err); }); // 输出1 1
-
链式调用、问题检测工具
-
链式调用
链式操作不能返回this,因为this是上一次的promise,而我们需要返回的是一个全新的promise
const isFunction = (value) => typeof value === 'function'; class MyPromise { constructor(executor) { this.state = 'pending'; // 初始状态:fulfilled,rejected this.value = undefined; // 成功的返回值 this.reason = undefined; // 失败的返回值 this.onFullFilledCallbacks = []; this.onRejectedCallbacks = []; let resovle = (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()); } try { executor(resovle, reject); } catch (err) { reject(err); } } then(onFullFilled, onRejected) { onFullFilled = isFunction(onFullFilled) ? onFullFilled : data => data; onRejected = isFunction(onRejected) ? onRejected : err => { throw err; } // 每一次调用then, 都会有一个p2 const p2 = new MyPromise((resolve, reject) => { // 每当new MyPromise的时候,里面的代码是同步执行的 let x; // 同步情况 if (this.state === 'fullFilled') { setTimeout(() => { try { x = onFullFilled(this.value); // resolve(x); // 判断返回值是否为promise,然后作相应的处理 resolvePromise(p2, x, resolve, reject); } catch (err) { reject(err); } }, 0); } 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(() => { 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); }); } }) return p2; // 返回全新的promise } } function resolvePromise(p2, x, resolve, reject) { let called; if (p2 === x) { return reject(new TypeError('typeErr')); } if ((typeof x === 'object' && x !== null) || typeof x === 'function') { try { let then = x.then; if (typeof then === 'function') { then.call(x, y => { if (called) return; called = true; // console.log(y); // resolve(y); resolvePromise(p2, y, resolve, reject); }, r => { if (called) return; called = true; // console.log(r) reject(r); }) } else { if (called) return; called = true; resolve(x); } } catch (err) { if (called) return; called = true; reject(err); } } else { resolve(x); } } const p1 = new MyPromise((resolve, reject) => { // setTimeout(() => { resolve(1); // reject(1); // }, 1000) }); const p2 = p1.then((res) => { // console.log(res); // 这里希望能够链式操作、返回一个promise return new MyPromise((resolve, reject) => { resolve(new MyPromise((resolve, reject) => { resolve(new MyPromise((resolve, reject) => { resolve(new MyPromise((resolve, reject) => { resolve(1000); })); })); })); }) }, (err) => { console.log(err); // return err + 2; }); p2.then((res) => { // 希望res能够拿到上一次回调的结果 console.log(res, 'success'); }, (err) => { console.log(err); }); MyPromise.defer = MyPromise.deferred = function() { let dfd = {}; dfd.promise = new MyPromise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }); return dfd; }; // 安装promises-aplus-tests工具测试 module.exports = MyPromise;
-
问题检测
安装promises-aplus-tests:
npm i promises-aplus-tests -g
终端输入如下命令进行检测:
promises-aplus-tests index.js
输出这样就说明代码没有问题
-