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
Promises/A+ 规范可在这里查看
Promises/A+
promise 有 3 个状态,分别为 pending, fulfilled 和 rejected
promise
3
pending
fulfilled
rejected
// promise 三种状态 const PENDING = 'pending' const FULFILLED = 'fulfilled' const REJECTED = 'rejected' // MyPromise 构造函数 function MyPromise (fn) { // 初始化状态 this.state = PENDING this.result = void 0 this.handlerQueue = [] let resolve = (value) => { transitionState(this, FULFILLED, value) } let reject = (reason) => { transitionState(this, REJECTED, reason) } // 调用 Promise 构造函数回调 try { fn(resolve, reject) } catch (error) { reject(error) } }
状态迁移方法,即调用了 fn(resolve, reject) 中的 resolve, reject 方法后,需要改变 promise 状态:
fn(resolve, reject)
resolve, reject
pending --> fulfilled
pending --> rejected
function transitionState (promise, state, result) { if (promise.state !== PENDING) return promise.state = state promise.result = result // 这里先占个坑位 }
then 方法返回的是一个新的 Promise 实例(注意:不是原来那个 Promise 实例),只有这样才能不断的链式调用,依次改变状态
then
Promise
MyPromise.prototype.then = function (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { let handler = { onFulfilled, onRejected, resolve, reject } // 若当前状态为 pending 则将其放在 handlerQueue 队列中,等待 resolve 或 reject 方法改变其状态 // 否则直接调用 then 方法中的 resolve 或 reject 回调函数 if (this.state ==== PENDING) { this.handlerQueue.push(handler) } else { dispatchHandler(handler, this.state, this.result) } }) }
const isFunction = arg => typeof arg === 'function' const delay = (fn, time = 0) => (...args) => { setTimeout(() => fn(...args), time) } // 异步执行 then 回调 const dispatchHandler = delay((handler, state, result) => { let { onFulfilled, onRejected, resolve, reject } = handler if (state === FULFILLED) { let finalValue = isFunction(onFulfilled) ? onFulfilled(result) : result resolve(finalValue) } else if (state === REJECTED) { let finalReason = isFunction(onRejected) ? onRejected(result) : result reject(finalReason) } })
以上代码,只支持 Promise 回调函数参数 resolve 和 reject 同步调用的情况,如下示例代码:
resolve
reject
// 支持 let myPromise = new MyPromise((resolve, reject) => { // resolve 同步调用 resolve('同步调用 value') }) myPromise.then((value) => { console.log('value: ', value) }, (reason) => { console.log('reason: ', reason) })
但是,使用异步调用不支持,如下示例代码:
// 暂不支持 let myPromise = new MyPromise((resolve, reject) => { // resolve 异步调用 setTimeout(() => { resolve('异步调用 value') }) }) myPromise.then((value) => { console.log('value: ', value) }, (reason) => { console.log('reason: ', reason) })
之所以不支持异步调用 resolve 或 reject,是因为 then 方法中如下代码片段:
resolve 或 reject
// 当 resolve 为异步调用,then 方法执行时,promise 状态为 pending。 // 所以 then 回调函数 onFulfilled 和 onRejected 在 handlerQueue 队列里,没有被调用 if (this.state ==== PENDING) { this.handlerQueue.push(handler) } else { // ... }
为支持 resolve、reject 异步调用,状态迁移方法 transitionState,做如下修改:
transitionState
function transitionState (promise, state, result) { if (promise.state !== PENDING) return promise.state = state promise.result = result // 新增代码开始 promise.handlerQueue.forEach(handler => { dispatchHandler(handler, state, result) }) // 新增代码结束 }
因为 catch 方法是 .then(null, onRejected) 的别名,所以实现 catch 代码如下:
catch
.then(null, onRejected)
MyPromise.prototype.catch = function (onRejected) { return this.then(null, onRejected) }
如上,简单实现了 promise,支持链式调用 then 和 catch
then 和 catch
欢迎关注无广告文章公众号:学前端
promise-aplus-impl
The text was updated successfully, but these errors were encountered:
gauseen
No branches or pull requests
Promises/A+
规范可在这里查看promise
有3
个状态,分别为pending
,fulfilled
和rejected
pending
状态fulfilled
或rejected
状态fulfilled
状态rejected
状态状态迁移方法,即调用了
fn(resolve, reject)
中的resolve, reject
方法后,需要改变promise
状态:pending --> fulfilled
pending --> rejected
then
方法返回的是一个新的Promise
实例(注意:不是原来那个Promise
实例),只有这样才能不断的链式调用,依次改变状态以上代码,只支持 Promise 回调函数参数
resolve
和reject
同步调用的情况,如下示例代码:但是,使用异步调用不支持,如下示例代码:
之所以不支持异步调用
resolve 或 reject
,是因为then
方法中如下代码片段:为支持
resolve
、reject
异步调用,状态迁移方法transitionState
,做如下修改:因为
catch
方法是.then(null, onRejected)
的别名,所以实现catch
代码如下:如上,简单实现了
promise
,支持链式调用then 和 catch
欢迎关注无广告文章公众号:学前端
参考
promise-aplus-impl
The text was updated successfully, but these errors were encountered: