Promise
实现原理:3 个状 2 个 结果处理函数 1 个对外方法
- 内部定义一个状态,两上值,两个数组
- 提供两个方法设置状态、并依次执行回调数组/链式
- 两个方法传给外部的 fn
- then 后者依赖前者返回值
考察点:
- 如何实现 then 链式调用:回调数组,执行时机
简版:
- 只考虑 resolve
js
// let task = new Promise(rFn)
// task.then(res => {})
function myPromise(exe) {
this.state = 'pending'
this.value = null
this.cbs = []
const resolve = value => {
this.value = value
this.state = 'fullfilled'
this.cbs.forEach(cb => cb(value))
}
// 省略 reject
exe(resolve, )
}
myPromise.prototype.then = function (cb) {
return new Promise(resolve => {
const _cb = value => {
const ret = cb(value) // 获取返回值,向后传递
resolve(ret) // 链式关键
}
// 省略 reject cb
if (this.state === 'fulfilled') {
_cb(this.value)
} else if (this.state === 'pending') {
this.cbs.push(_cb)
}
// 省略 reject 分支
})
}
// test
let sleep = ms => new myPromise(r => setTimeout(() => r('sleep done'), ms))
let d = sleep(2000)
.then(v => { console.log(1, v); return v + ' from 1'})
.then(d => console.log(2, d))
js
const PENDING = 'pending'
const FULFILLED = 'fullfilled'
const REJECTED = 'rejected'
class Promise {
constructor(executor) {
this.state = PENDING
this.value = null
this.reason = null
this.onFulfilledCbs = []
this.onRejectedCbs = []
const resolve = value => {
// 这里不要用 function,会有 this 问题
if (this.state !== PENDING) return
this.state = FULFILLED
this.value = value
this.onFulfilledCbs.forEach(cb => cb(this.value))
}
const reject = reason => {
if (this.state !== PENDING) return
this.state = REJECTED
this.reason = reason
this.onRejectedCbs.forEach(cb => cb(this.reason))
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
const fulfilledCb = value => {
const _value =
typeof onFulfilled === 'function' ? onFulfilled(value) : value
resolve(_value) // 实现 then 的关键 1
}
const rejectedCb = reason => {
const _reason =
typeof onRejected === 'function' ? onRejected(reason) : reason
reject(_reason)
}
if (this.state === FULFILLED) {
fulfilledCb(this.value)
} else if (this.state === REJECTED) {
rejectedCb(this.reason)
} else if (this.state === PENDING) {
this.onFulfilledCbs.push(fulfilledCb) // 实现 then 的关键 2
this.onRejectedCbs.push(rejectedCb)
}
})
}
}
// test
let sleep = ms => new Promise(r => setTimeout(() => r('sleep done'), ms))
let d = sleep(2000)
.then(v => { console.log(1, v); return v + ' from 1'})
.then(d => console.log(2, d))