We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Promise/A+
pending ———> Fulfilled | |———————> Rejected
实现了 Promise 的构造函数
class MyPromise { constructor(executor) { this.value = null; this.reason = null; const resolve = value => { this.value = value; }; const reject = reason => { this.reason = reason; }; try { executor(resolve, reject); } catch (error) { reject(error); } } }
将 Promise 的三种状态引入实现,并且在正确的时机改变状态
const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; class MyPromise { constructor(executor) { this.value = null; this.reason = null; this.state = PENDING; const resolve = value => { if (this.state === PENDING) { this.value = value; this.state = FULFILLED; } }; const reject = reason => { if (this.state === PENDING) { this.reason = reason; this.state = REJECTED; } }; try { executor(resolve, reject); } catch (error) { reject(error); } } }
then 函数,需要在 Promise fulfilled 的时候调用成功回调, rejected 时调用失败回调
const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; class MyPromise { constructor(executor) { this.value = null; this.reason = null; this.state = PENDING; const resolve = (value) => { if (this.state === PENDING) { this.value = value; this.state = FULFILLED; } }; const reject = (reason) => { if (this.state === PENDING) { this.reason = reason; this.state = REJECTED; } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { // 判别传入的值,是否为函数,如果不是,需要给予缺省值 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (_) => _; onRejected = typeof onRejected === 'function' ? onRejected : (_) => { throw _; }; if (this.state === FULFILLED) { onFulfilled(this.value); } if (this.state === REJECTED) { onRejected(this.reason); } } }
通过两个数组保存 then 方法传入的函数,并且在 resolve 或 reject 的时候调用数组内的方法
const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; class MyPromise { constructor(executor) { this.value = null; this.reason = null; this.state = PENDING; this.onFulfilledCbs = []; this.onRejectedCbs = []; const resolve = (value) => { if (this.state === PENDING) { this.value = value; this.state = FULFILLED; this.onFulfilledCbs.forEach((fn) => fn()); } }; const reject = (reason) => { if (this.state === PENDING) { this.reason = reason; this.state = REJECTED; this.onRejectedCbs.forEach((fn) => fn()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { // 判别传入的值,是否为函数,如果不是,需要给予缺省值 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (_) => _; onRejected = typeof onRejected === 'function' ? onRejected : (_) => { throw _; }; this.onFulfilledCbs.push(() => onFulfilled(this.value)); this.onRejectedCbs.push(() => onRejected(this.value)); } }
Then 方法需要返回一个 Promise
const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; class MyPromise { constructor(executor) { this.value = null; this.reason = null; this.state = PENDING; this.onFulfilledCbs = []; this.onRejectedCbs = []; const resolve = (value) => { if (this.state === PENDING) { this.value = value; this.state = FULFILLED; this.onFulfilledCbs.forEach((fn) => fn()); } }; const reject = (reason) => { if (this.state === PENDING) { this.reason = reason; this.state = REJECTED; this.onRejectedCbs.forEach((fn) => fn()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { // 判别传入的值,是否为函数,如果不是,需要给予缺省值 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (_) => _; onRejected = typeof onRejected === 'function' ? onRejected : (_) => { throw _; }; return new MyPromise((resolve, reject) => { const fulfilledPromise = () => { setTimeout(() => { try { resolve(onFulfilled(this.value)); } catch (error) { reject(error); } }); }; const rejectPromise = () => { setTimeout(() => { try { reject(onRejected(this.reason)); } catch (error) { reject(error); } }); }; if (this.state === PENDING) { this.onFulfilledCbs.push(fulfilledPromise); this.onRejectedCbs.push(rejectPromise); } else if (this.state === FULFILLED) { fulfilledPromise(); } else if (this.state === REJECTED) { rejectPromise(); } }); } }
到这里,其实 then 方法还有一个很重要的点没有实现,就是在then方法里,是可以通过回调函数 return 一个 Promise 值的,而这时,这个 Promise 会被展开并作为当前链式调用的决议值
const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; class MyPromise { constructor(executor) { this.value = null; this.reason = null; this.state = PENDING; this.onFulfilledCbs = []; this.onRejectedCbs = []; const resolve = (value) => { if (this.state === PENDING) { this.value = value; this.state = FULFILLED; this.onFulfilledCbs.forEach((fn) => fn()); } }; const reject = (reason) => { if (this.state === PENDING) { this.reason = reason; this.state = REJECTED; this.onRejectedCbs.forEach((fn) => fn()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { // 判别传入的值,是否为函数,如果不是,需要给予缺省值 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (_) => _; onRejected = typeof onRejected === 'function' ? onRejected : (_) => { throw _; }; const nextPromise = new MyPromise((resolve, reject) => { const fulfilledPromise = () => { setTimeout(() => { try { resolvePromise(nextPromise, onFulfilled(this.value), resolve, reject); } catch (error) { reject(error); } }); }; const rejectPromise = () => { setTimeout(() => { try { resolvePromise(nextPromise, onRejected(this.reason), resolve, reject); } catch (error) { reject(error); } }); }; if (this.state === PENDING) { this.onFulfilledCbs.push(fulfilledPromise); this.onRejectedCbs.push(rejectPromise); } else if (this.state === FULFILLED) { fulfilledPromise(); } else if (this.state === REJECTED) { rejectPromise(); } }); return nextPromise; } } function resolvePromise(promise, value, resolve, reject) { // 防止循环 if (promise === value) { reject(new TypeError('Chaining cycle')); } // 判断 value 是否为一个 thenable 值 if ( value !== null && (typeof value === 'object' || typeof value === 'function') && typeof value.then === 'function' ) { try { value.then( (v) => { resolvePromise(promise, v, resolve, reject); }, (err) => { reject(err); } ); } catch (error) { reject(error); } } else { resolve(value); } }
const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; class MyPromise { constructor(executor) { this.value = null; this.reason = null; this.state = PENDING; this.onFulfilledCbs = []; this.onRejectedCbs = []; const resolve = (value) => { if (this.state === PENDING) { this.value = value; this.state = FULFILLED; this.onFulfilledCbs.forEach((fn) => fn()); } }; const reject = (reason) => { if (this.state === PENDING) { this.reason = reason; this.state = REJECTED; this.onRejectedCbs.forEach((fn) => fn()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { // 判别传入的值,是否为函数,如果不是,需要给予缺省值 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (_) => _; onRejected = typeof onRejected === 'function' ? onRejected : (_) => { throw _; }; const nextPromise = new MyPromise((resolve, reject) => { const fulfilledPromise = () => { setTimeout(() => { try { resolvePromise(nextPromise, onFulfilled(this.value), resolve, reject); } catch (error) { reject(error); } }); }; const rejectPromise = () => { setTimeout(() => { try { resolvePromise(nextPromise, onRejected(this.reason), resolve, reject); } catch (error) { reject(error); } }); }; if (this.state === PENDING) { this.onFulfilledCbs.push(fulfilledPromise); this.onRejectedCbs.push(rejectPromise); } else if (this.state === FULFILLED) { fulfilledPromise(); } else if (this.state === REJECTED) { rejectPromise(); } }); return nextPromise; } catch(onRejected) { return this.then(null, onRejected); } } function resolvePromise(promise, value, resolve, reject) { // 防止循环 if (promise === value) { reject(new TypeError('Chaining cycle')); } // 判断 value 是否为一个 thenable 值 if ( value !== null && (typeof value === 'object' || typeof value === 'function') && typeof value.then === 'function' ) { try { value.then( (v) => { resolvePromise(promise, v, resolve, reject); }, (err) => { reject(err); } ); } catch (error) { reject(error); } } else { resolve(value); } }
根据上述步骤,大致完成了 Promise 的一个实现,经过我的测试大部分情况应该是都能通过的。
我和真正的 Promise/A+ 规范进行了比对,又参考了很多大神的实现方式,了解到想要真正做到完全的符合规范是需要做非常多判断的,需要做大量的工作,感觉理解规范的意图和其作用非常困难,我还是准备偷个懒,我已经大致了解了如何去实现一个 Promise, 最后只剩一些小细节了,这部分细节准备先放一放,等下次有空好好参照规范写一下
#前端
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Promise/A+
规范概览1. Promise 是一个状态机,状态变化不可逆
2. Promise 有 then 方法,可被调用多次,返回 Promise 对象
3. 支持链式调用,内部记录 value,用来记录上次计算的结果值,如果报错,说明保存的是异常
实现步骤
实现 Promise 的基本框架
实现了 Promise 的构造函数
增加状态机
将 Promise 的三种状态引入实现,并且在正确的时机改变状态
实现 then 方法
then 函数,需要在 Promise fulfilled 的时候调用成功回调, rejected 时调用失败回调
实现异步调用
通过两个数组保存 then 方法传入的函数,并且在 resolve 或 reject 的时候调用数组内的方法
实现 then 基本的链式调用
Then 方法需要返回一个 Promise
到这里,其实 then 方法还有一个很重要的点没有实现,就是在then方法里,是可以通过回调函数 return 一个 Promise 值的,而这时,这个 Promise 会被展开并作为当前链式调用的决议值
实现 then 对于 Promise 值的处理
实现 catch 的异常处理
总结
根据上述步骤,大致完成了 Promise 的一个实现,经过我的测试大部分情况应该是都能通过的。
我和真正的 Promise/A+ 规范进行了比对,又参考了很多大神的实现方式,了解到想要真正做到完全的符合规范是需要做非常多判断的,需要做大量的工作,感觉理解规范的意图和其作用非常困难,我还是准备偷个懒,我已经大致了解了如何去实现一个 Promise, 最后只剩一些小细节了,这部分细节准备先放一放,等下次有空好好参照规范写一下
参考资料
#前端
The text was updated successfully, but these errors were encountered: