Promise通过构造函数的回调函数callback,以及callback的参数resolve和reject,Promise的实例是thenabel对象,then方法的参数是onFulfilled/onRejected函数,其参数是value/reason,取决于Promise的状态
promiseA+规范
1. 三种状态,流转如下
pending => resolve(value) => fulfilled
pending => reject(reason) => rejected
2. promise.then(onFulfilled, onRejected)
onFulfilled/onRejected若不是函数,则忽略
onFulfilled/onRejected函数在状态发生流转时被调用,且仅执行一次
onFulfilled/onRejected函数的执行环境是微任务里
3. then方法可以被调用多次
``` js
promise.then(onResolved)
promise.then(onResolved)
promise.then(onResolved)
promise.then(onResolved)
// promise的状态从 pending 变成 fulfilled/rejected 后
// 同一个promise实例的所有的 onResolved/onRejected 回调函数都会一一执行
```
4. then的返回值是一个新的 promise 实例
5. resolvePromise
``` js
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MPromise {
FULFILLED_CALLBACK_LIST = []
REJECTED_CALLBACK_LIST = []
_status = PENDING
constructor(fn) {
this.status = PENDING
this.value = null
this.reason = null
try {
fn(this.resolve.bind(this), this.reject.bind(this))
} catch(e) {
this.reject(e)
}
}
get stauts() {
return this._status
}
set status(newStatus) {
this._status = newStatus
switch(newStatus) {
case FULFILLED: {
this.FULFILLED_CALLBACK_LIST.forEach(cb => {
cb(this.value)
})
break
}
case REJECTED: {
this.REJECTED_CALLBACK_LIST.forEach(cb => {
cb(this.reason)
})
break
}
}
}
resolve(value) {
if (this.status === PENDING) {
this.status = FULFILLED
this.value = value
}
}
reject(reason) {
if (this.status === REJECTED) {
this.status = REJECTED
this.reason = REJECTED
}
}
then(onFulfilled, onRejected) {
const onRealFulfilled = this.isFunction(onFulfilled) ? onFulfilled : value => value
const onRealRejected = this.isFunction(onRejected) ? onRejected : reason => {
throw reason
}
const promise2 = new MPromise((resolve, reject) => {
const fulfilledMicrotask = () => {
queueMicrotask(() => {
try {
const x = onRealFulfilled(this.value)
this.resolvePromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
})
}
const rejectedMicrotask = () => {
queueMicrotask(() => {
try {
const x = onRejectedMicrotask(this.reason)
this.resolvePromise(promise2, x, resolve, reject)
} catch(e) {
reject(e)
}
})
}
switch(this.status) {
case FULFILLED: {
fulfilledMicrotask()
break
}
case REJECTED: {
rejectedMicrotask()
break
}
case PENDING: {
this.FULFILLED_CALLBACK_LIST.push(fulfilledMicrotask)
this.REJECTED_CALLBACK_LIST.push(rejectedMicrotask)
}
}
})
return promise2
}
resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
reject(new TypeError('promise和返回值重复'))
}
if (x instanceof MPromise) {
queueMicrotask(() => {
x.then(y => {
this.resolvePromise(promise2, y, resolve, reject)
}, reject)
})
} else if (typeof x === 'object' || this.isFunction(x)) {
if (x === null) {
resolve(x)
}
let then = null
try {
then = x.then
} catch(e) {
reject(e)
}
if (this.isFunction(then)) {
let called = false
try {
then.call(x, y => {
if (called) return
called = true
this.resolvePromise(promise2, y, resolve, reject)
}, r => {
if (called) return
called = true
reject(r)
})
} catch(e) {
if (called) return
reject(e)
}
} else {
resolve(x)
}
} else {
resolve(x)
}
}
static resolve(value) {
if (value instanceof MPromise) {
return value
}
return new MPromise(resolve => {
resolve(value)
})
}
static reject(reason) {
return new MPromise((resolve, reject) => {
reject(reason)
})
}
isFunction(param) {
return typeof param === 'function'
}
}
```