tc39.es/ecma262/mul… 27.2 Promise Objects
描述
一个 Promise 是一个代理,它代表一个在创建 promise 时不一定已知的值。它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise,以便在将来的某个时间点提供该值。
一个 Promise 必然处于以下几种状态之一:
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled):意味着操作成功完成。
- 已拒绝(rejected):意味着操作失败。
一个待定的 Promise 最终状态可以是已兑现并返回一个值,或者是已拒绝并返回一个原因(错误)。当其中任意一种情况发生时,通过 Promise 的 then 方法串联的处理程序将被调用。如果绑定相应处理程序时 Promise 已经兑现或拒绝,这处理程序将被立即调用,因此在异步操作完成和绑定处理程序之间不存在竞态条件。
如果一个 Promise 已经被兑现或拒绝,即不再处于待定状态,那么则称之为已敲定(settled)。
Promise 并发
Promise 类提供了四个静态方法来促进异步任务的并发:
-
Promise.all()在所有传入的 Promise 都被兑现时兑现;在任意一个 Promise 被拒绝时拒绝。
-
Promise.allSettled()在所有的 Promise 都被敲定时兑现。
-
Promise.any()在任意一个 Promise 被兑现时兑现;仅在所有的 Promise 都被拒绝时才会拒绝。
-
Promise.race()在任意一个 Promise 被敲定时敲定。换句话说,在任意一个 Promise 被兑现时兑现;在任意一个的 Promise 被拒绝时拒绝。
静态方法
Promise.all(iterable)
接受一个 Promise 可迭代对象作为输入,并返回单个 Promise。返回的 Promise 在所有输入的 Promise 都兑现时(包括传入的可迭代对象为空时)被兑现,其值为一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,返回的 Promise 也会被拒绝,并返回第一个拒绝的原因。
const promise1 = Promise.resolve(3)
const promise2 = 5
const promise3 = new Promise((resolve) => {
resolve(4)
})
const all = Promise.all([promise1, promise2, promise3]);
all.then(res => {
console.log(res); //[3,5,4]
}).catch(err => {
console.log(err);
})
Promise.allSettled(iterable)
接受一个 Promise 可迭代对象作为输入,并返回单个 Promise。返回的 Promise 在所有输入的 Promise 都敲定时兑现(包括传入的可迭代对象为空时),其值为一个描述每个 Promise 结果的对象数组。
const promise1 = Promise.resolve(3)
const promise2 = Promise.reject(5)
const promise3 = new Promise((resolve) => {
resolve(4)
})
const all = Promise.allSettled([promise1, promise2, promise3]);
all.then(res => {
console.log(res); //[{ status: 'fulfilled', value: 3 },{ status: 'rejected', reason: 5 },{ status: 'fulfilled', value: 4 }]
}).catch(err => {
console.log(err);
})
Promise.any(iterable)
接受一个 Promise 可迭代对象作为输入,并返回单个 Promise。返回的 Promise 在任何输入的 Promise 兑现时兑现,其值为第一个兑现的值。如果所有输入的 Promise 都被拒绝(包括传入的可迭代对象为空时),返回的 Promise 将以带有一个包含拒绝原因的数组的 AggregateError 拒绝。
const promise1 = Promise.resolve(3)
const promise2 = Promise.reject(5)
const promise3 = new Promise((resolve) => {
resolve(4)
})
const all = Promise.any([promise1, promise2, promise3]);
all.then(res => {
console.log(res);//3
}).catch(err => {
console.log(err);
})
Promise.race(iterable)
接受一个 Promise 可迭代对象作为输入,并返回单个 Promise。返回的 Promise 与第一个敲定(兑现或拒绝)的 Promise 的最终状态保持一致。
const promise1 = Promise.reject(3)
const promise2 = Promise.reject(5)
const promise3 = new Promise((resolve) => {
resolve(4)
})
const all = Promise.race([promise1, promise2, promise3]);
all.then(res => {
console.log(res);//3
}).catch(err => {
console.log(err);
})
Promise.reject()
返回一个新的 Promise 对象,该对象以给定的原因拒绝。
Promise.resolve()
返回一个新的 Promise 对象,该对象以给定的值兑现。如果值是一个 thenable 对象(即具有 then 方法),则返回的 Promise 对象会“跟随”该 thenable 对象,采用其最终的状态;否则,返回的 Promise 对象会以该值兑现。通常,如果你不知道一个值是否是 Promise,那么最好使用 Promise.resolve(value) 将其转换成 Promise 对象,并将返回值作为 Promise 来处理。
const promise1 = Promise.reject(3)
const promise2 = Promise.resolve(4)
promise1.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
promise2.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
实例方法
-
Promise.prototype.then()将一个兑现处理器和拒绝处理器附加到 Promise 上,并返回一个新的 Promise,解决为调用处理器得到的返回值,或者如果 Promise 没有被处理(即相关处理器onFulfilled或onRejected不是函数),则以原始敲定值解决。 -
Promise.prototype.catch()将一个拒绝处理回调函数附加到 Promise 上,并返回一个新的 Promise,如果回调被调用,则解决为回调的返回值,如果 Promise 被兑现,解决为其原始兑现值。 -
Promise.prototype.finally()将一个处理器附加到 Promise 上,并返回一个新的 Promise,当原始 Promise 被解决时解决。无论 Promise 是否被兑现还是被拒绝,处理器都会在 Promise 敲定时被调用。
实现Promise
Promise/A+ 规范要点
- 状态转换:Promise 必须处于三种状态之一:pending、fulfilled 或 rejected。
- 状态转换不可逆:一旦从 pending 转变为 fulfilled 或 rejected,状态就不能再改变。
- then 方法:Promise 必须提供一个
then方法,用于注册回调函数。 - 异步执行:
then方法的回调函数必须异步执行。 - 链式调用:
then方法必须返回一个新的 Promise。
详细规范
一、Promise状态
Promise代表异步操作的最终结果,它必须处于以下三种状态之一:
- Pending(等待态):初始状态,既不是成功也不是失败状态。此时,Promise可以转变为Fulfilled或Rejected状态。
- Fulfilled(执行态):表示操作成功完成。当Promise处于Fulfilled状态时,它不能转换为其他状态,并且必须拥有一个不可变的终值。
- Rejected(拒绝态):表示操作失败。当Promise处于Rejected状态时,它同样不能转换为其他状态,并且必须拥有一个不可变的原因。
二、then方法
与Promise交互的主要方式是通过其then方法。then方法用于注册回调函数,以便在Promise被履行(Fulfilled)或被拒绝(Rejected)时执行相应的操作。
- 参数:then方法接受两个参数,分别是onFulfilled和onRejected。这两个回调函数都是可选的,如果不提供,则会被忽略。
- onFulfilled:在Promise被履行后,以Promise的值作为第一个参数调用此函数。在Promise被履行之前,不能调用它,且其调用次数不可超过一次。
- onRejected:在Promise被拒绝后,以Promise的原因作为第一个参数调用此函数。在Promise被拒绝之前,不能调用它,且其调用次数不可超过一次。
- 调用时机:onFulfilled和onRejected只有在执行环境堆栈仅包含平台代码时才可被调用。这确保了它们异步执行,即在then方法被调用的事件循环回合之后,并且使用一个新的堆栈。
- 调用要求:onFulfilled和onRejected必须被作为函数调用(即没有this值)。如果Promise被履行或拒绝,所有相应的回调函数必须按照它们的原始调用顺序执行。
- 返回值:then方法必须返回一个Promise对象。如果onFulfilled或onRejected返回一个值x,则会运行Promise解决过程来处理返回值。如果回调函数抛出异常,则Promise会被拒绝。
三、Promise解决过程
Promise解决过程是一个抽象操作,它接受一个Promise和一个值作为输入。该过程会根据值的类型和状态,决定如何处理这个Promise对象。
- 如果x是一个thenable对象(即定义了then方法的对象或函数):Promise会尝试采用x的状态。这意味着,如果x至少有一些类似Promise的行为,Promise实现将能够与之互操作。
- 如果x不是一个thenable对象:Promise会用值x来履行。
在处理thenable对象时,Promise/A+规范还规定了一些特殊情况的处理方式,例如:
- 如果promise和x引用同一个对象,则以TypeError为原因拒绝promise。
- 如果x是pending状态,则promise必须保持pending状态,直到x被履行或拒绝。
- 如果获取属性x.then导致抛出异常e,则以e为原因拒绝promise。
四、其他重要规定
- 链式调用:Promise对象的方法调用通常会返回一个新的Promise对象,这允许进行链式调用。
- 错误处理:除了then方法外,Promise还提供了catch方法用于注册失败回调函数,以及finally方法用于注册无论成功或失败都会执行的回调函数。
- 状态不变性:一旦Promise的状态从Pending转变为Fulfilled或Rejected,它就不能再改变。
代码实现
第一步: 搭建框架
- Promise 是一个构造函数(ES6 中使用类)
- new Promise 时传入一个执行函数,并且执行函数是立即执行的
- 执行函数接收两个参数
resolve 函数 和 reject 函数,并且均能够接收参数 - Promise 的实例上有一个
then方法,then方法接收两个参数(onFulfilled, onRejected)
//1.1 Promise 是一个构造函数(ES6 中使用类)
class MyPromise {
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
constructor(executor) {
///#region
//1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`,并且均能够接收参数
function resolve(value) {}
function reject(reason) {}
//#endregion
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
try { //防止出错放入try
executor(resolve, reject) //1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`
} catch (error) {
throw error
}
}
// 1.4Promise 的实例上有一个 `then` 方法, `then` 方法接收两个参数
then(onFulfilled, onRejected) {
}
}
const promise = new MyPromise(() => {
console.log("立即执行");
})
promise.then()
第二步: promise的状态值
-
Promise 需要一个状态值,初始值为pending
-
执行函数调用 resolve 或者 reject 时改变状态,并且只能从从 “pending ” 到 “fulfilled ”,或者从 “fulfilled” 到 “ rejected”
const state = {
pending: 'pending',
fulfilled: 'fulfilled',
rejected: 'rejected',
}
//1.1 Promise 是一个构造函数(ES6 中使用类)
class MyPromise {
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
constructor(executor) {
// 2.1 Promise 需要一个状态值,初始值为pending
this.state = state.pending
//1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`,并且均能够接收参数
function resolve(value) {
//2.2 执行函数调用 resolve 时改变状态 能且只能: pending-->fulfilled
if (this.state === state.pending) {
this.state = state.fulfilled
console.log(value);
}
}
function reject(reason) {
//2.2 执行函数调用 reject 时改变状态 能且只能: pending-->rejected
if (this.state === state.pending) {
this.state = state.rejected
console.log(reason);
}
}
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
try { //防止出错放入try
executor(resolve, reject) //1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`
} catch (error) {
throw error
}
}
// 1.4Promise 的实例上有一个 `then` 方法, `then` 方法接收两个参数
then(agr1, arg2) {
}
}
const promise = new MyPromise(() => {
console.log("立即执行");
})
promise.then()
第三步: 处理then
-
onFulfilled和onRejected都是可选参数:- 如果
onFulfilled不是函数,必须将其忽略 - 如果
onRejected不是函数,必须将其忽略
- 如果
-
如果
onFulfilled、onRejected是函数- 当
promise解决后其必须被调用,其第一个参数为promise的终值、拒因 - 在
promise解决前其不可被调用 - 其调用次数不可超过一次
- 当
-
调用时机: Promises/A+ 规范指出
onFulfilled和onRejected并不是 promise 解决或者拒绝后就立即调用的,而是放到的任务队列中,具体何时执行需要根据实现的机制来。实践中要确保onFulfilled和onRejected函数异步地执行,并且应该是在then方法被调用后的新一轮事件循环的新执行栈中执行。这个机制可以采用 "宏任务(macro-task)"机制来实现,也可以采用 “微任务(micro-task)” 机制来实现. -
调用要求:
onFulfilled和onRejected必须被作为函数调用,也就是说在 严格模式(strict) 中,函数this的值为undefined;在非严格模式中其为全局对象。 -
then 方法可以被同一个 promise 调用多次
-
当 promise 解决后,所有的
onFulfilled需按照其注册顺序依次回调 -
当 promise 拒绝后,所有的
onRejected需按照其注册顺序依次回调
-
-
then 方法必须返回一个 Promise 对象 (放到后面写 第四步)
const state = {
pending: 'pending',
fulfilled: 'fulfilled',
rejected: 'rejected',
}
//1.1 Promise 是一个构造函数(ES6 中使用类)
class MyPromise {
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
constructor(executor) {
// 2.1 Promise 需要一个状态值,初始值为pending
this.state = state.pending
// 3.2 记录promise 的终值/拒因
this.value = undefined
this.reason = undefined
//3.5 then 方法可以被同一个 promise 调用多次 需按照其注册顺序依次回调
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
//1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`,并且均能够接收参数
const resolve = (value) => {
//2.2 执行函数调用 resolve 时改变状态 能且只能: pending-->fulfilled
if (this.state === state.pending) {
this.state = state.fulfilled
this.value = value
//3.5 当 promise 解决后,所有的 `onFulfilled` 需按照其注册顺序依次回调
this.onFulfilledCallbacks && this.onFulfilledCallbacks.forEach(onFulfilled => {
onFulfilled(value)
});
}
}
const reject = (reason) => {
//2.2 执行函数调用 reject 时改变状态 能且只能: pending-->rejected
if (this.state === state.pending) {
this.state = state.rejected
this.reason = reason
//3.5 当 promise 拒绝后,所有的 `onRejected` 需按照其注册顺序依次回调
this.onRejectedCallbacks && this.onRejectedCallbacks.forEach(onRejected => {
onRejected(reason)
})
}
}
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
try { //防止出错放入try
executor(resolve, reject) //1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`
} catch (error) {
throw error
}
}
// 1.4Promise 的实例上有一个 `then` 方法, `then` 方法接收两个参数
then(onFulfilled, onRejected) {
// 3.2 onFulfilled, onRejected 在解决后其必须被调用 并且只能在解决后被调用
// 两个if是为了保证 new MyPromise里是同步代码时执行 else 是为了保证异步时执行
if (this.state === state.fulfilled) {
// 3.1 如果 `onFulfilled` 不是函数,必须将其忽略
if (typeof onFulfilled === 'function') {
//3.3 并不是 promise 解决或者拒绝后就立即调用的,而是放到宏任务或微任务任务队列中,
//3.3 确保异步地执行并且应该是在 `then` 方法被调用后的新一轮事件循环的新执行栈中执行
queueMicrotask(() => {
onFulfilled(this.value)
})
}
} else if (this.state === state.rejected) {
//3.1 `onRejected` 不是函数,必须将其忽略 这里是直接加入微任务队列
if (typeof onRejected === 'function') {
//3.3 并不是 promise 解决或者拒绝后就立即调用的,而是放到宏任务或微任务任务队列中,
//3.3 确保异步地执行并且应该是在 `then` 方法被调用后的新一轮事件循环的新执行栈中执行
queueMicrotask(() => {
onRejected(this.reason)
})
}
} else { //这里是加入待执行队列,当状态改变时才执行
// 3.2 & 3.3 & 3,5 记录下onFulfilled, onRejected以备执行
if (typeof onFulfilled === 'function') {
this.onFulfilledCallbacks.push(value => {
queueMicrotask(() => {
onFulfilled(value)
})
})
}
if (typeof onRejected === 'function') {
this.onRejectedCallbacks.push(reason => {
queueMicrotask(() => {
onRejected(reason)
})
})
}
}
}
}
const promise = new MyPromise((resolve, reject) => {
console.log("立即执行");
setTimeout(() => {
resolve("resolve")
}, 2000)
})
promise.then(
res => {
console.log("res:", res);
}, err => {
console.log("err:", err);
}
)
第四步 then 方法必须返回一个 Promise 对象
- 如果
onFulfilled或者onRejected为函数且返回一个值x,则运行 Promise 解决过程:[[Resolve]](promise2, x)(先设为resolvePromise函数)Promise 解决过程:[[Resolve]](promise2, x)” 是指一个抽象的执行过程,这里可以直接理解成一个函数,后面会详细说明 - 如果
onFulfilled或者onRejected抛出一个异常e,则promise2必须拒绝并返回拒因e - 如果
onFulfilled不是函数且promise1已解决,promise2必须解决并返回与promise1相同的值 - 如果
onRejected不是函数且promise1已拒绝,promise2必须拒绝并返回与promise1相同的拒因
const state = {
pending: 'pending',
fulfilled: 'fulfilled',
rejected: 'rejected',
}
//4.1 Promise 解决过程
function promiseResolve(promise2, x) {
}
//1.1 Promise 是一个构造函数(ES6 中使用类)
class MyPromise {
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
constructor(executor) {
// 2.1 Promise 需要一个状态值,初始值为pending
this.state = state.pending
// 3.2 记录promise 的终值/拒因
this.value = undefined
this.reason = undefined
//3.5 then 方法可以被同一个 promise 调用多次 需按照其注册顺序依次回调
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
//1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`,并且均能够接收参数
const resolve = (value) => {
//2.2 执行函数调用 resolve 时改变状态 能且只能: pending-->fulfilled
if (this.state === state.pending) {
this.state = state.fulfilled
this.value = value
//3.5 当 promise 解决后,所有的 `onFulfilled` 需按照其注册顺序依次回调
this.onFulfilledCallbacks && this.onFulfilledCallbacks.forEach(onFulfilled => {
onFulfilled(value)
});
}
}
const reject = (reason) => {
//2.2 执行函数调用 reject 时改变状态 能且只能: pending-->rejected
if (this.state === state.pending) {
this.state = state.rejected
this.reason = reason
//3.5 当 promise 拒绝后,所有的 `onRejected` 需按照其注册顺序依次回调
this.onRejectedCallbacks && this.onRejectedCallbacks.forEach(onRejected => {
onRejected(reason)
})
}
}
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
try { //防止出错放入try
executor(resolve, reject) //1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`
} catch (error) {
throw error
}
}
// 1.4Promise 的实例上有一个 `then` 方法, `then` 方法接收两个参数
then(onFulfilled, onRejected) {
// 4.0 then 方法必须返回一个 Promise 对象
const promise2 = new MyPromise((resolve, reject) => {
// 3.2 onFulfilled, onRejected 在解决后其必须被调用 并且只能在解决后被调用
// 两个if是为了保证 new MyPromise里是同步代码时执行 else 是为了保证异步时执行
if (this.state === state.fulfilled) {
// 3.1 如果 `onFulfilled` 不是函数,必须将其忽略
if (typeof onFulfilled === 'function') {
//3.3 并不是 promise 解决或者拒绝后就立即调用的,而是放到宏任务或微任务任务队列中,
//3.3 确保异步地执行并且应该是在 `then` 方法被调用后的新一轮事件循环的新执行栈中执行
queueMicrotask(() => {
try {
//4.1 如果 `onFulfilled` 为函数且返回一个值 `x` ,则运行 Promise 解决过程
const x = onFulfilled(this.value)
x && promiseResolve(promise2, x)
} catch (error) {
//4.2 如果或者 `onFulfilled` 抛出一个异常 `e` ,则 `promise2` 必须拒绝并返回拒因 `e`
reject(error)
}
})
} else {
//4.3 如果 `onFulfilled` 不是函数且 `promise1` 已解决, `promise2` 必须解决并返回与 `promise1` 相同的值
resolve(this.value)
}
} else if (this.state === state.rejected) {
//3.1 `onRejected` 不是函数,必须将其忽略 这里是直接加入微任务队列
if (typeof onRejected === 'function') {
//3.3 并不是 promise 解决或者拒绝后就立即调用的,而是放到宏任务或微任务任务队列中,
//3.3 确保异步地执行并且应该是在 `then` 方法被调用后的新一轮事件循环的新执行栈中执行
queueMicrotask(() => {
try {
//4.1 如果 `onRejected` 为函数且返回一个值 `x` ,则运行 Promise 解决过程
const x = onRejected(this.reason)
x && promiseResolve(promise2, x)
} catch (error) {
//4.2 如果或者 `onRejected` 抛出一个异常 `e` ,则 `promise2` 必须拒绝并返回拒因 `e`
reject(error)
}
})
} else {
//4.4 如果 `onRejected` 不是函数且 `promise1` 已拒绝, `promise2` 必须拒绝并返回与 `promise1` 相同的拒因
reject(this.reason)
}
} else { //这里是加入待执行队列,当状态改变时才执行
// 3.2 & 3.3 & 3,5 记录下onFulfilled, onRejected以备执行
this.onFulfilledCallbacks.push(value => {
queueMicrotask(() => {
if (typeof onFulfilled === 'function') { //这里放进来是为了在执行时才判断是否为函数
try {
//4.1 如果 `onFulfilled` 为函数且返回一个值 `x` ,则运行 Promise 解决过程
const x = onFulfilled(value)
x && promiseResolve(promise2, x)
} catch (error) {
//4.2 如果 `onFulfilled`抛出一个异常 `e` ,则 `promise2` 必须拒绝并返回拒因 `e`
reject(error)
}
} else {
//4.3 如果 `onFulfilled` 不是函数且 `promise1` 已解决, `promise2` 必须解决并返回与 `promise1` 相同的值
resolve(value)
}
})
})
this.onRejectedCallbacks.push(reason => {
queueMicrotask(() => {
if (typeof onRejected === 'function') { //这里放进来是为了在执行时才判断是否为函数
try {
//4.1 如果 `onRejected` 为函数且返回一个值 `x` ,则运行 Promise 解决过程
const x = onRejected(reason)
x && promiseResolve(promise2, x)
} catch (error) {
//4.2 如果 `onRejected`抛出一个异常 `e` ,则 `promise2` 必须拒绝并返回拒因 `e`
reject(error)
}
} else {
//4.4 如果 `onRejected` 不是函数且 `promise1` 已拒绝, `promise2` 必须拒绝并返回与 `promise1` 相同的拒因
reject(reason)
}
})
})
}
})
return promise2
}
}
第五步 promise解决过程
-
如果
promise2和x指向同一对象,以TypeError为拒因拒绝promise2 -
如果
x为 Promise,依据状态不同: 可以并入3 不用处理- 如果
x处于待定状态,promise2需保持为待定状态直至x被解决或拒绝 - 如果
x处于兑现状态,用与x相同的终值解决promise2 - 如果
x处于拒绝状态,用与x相同的拒因拒绝promise2
- 如果
-
如果
x是一个对象或者函数-
把
x.then赋值给then -
如果取
x.then的值时抛出错误e,则以e为拒因拒绝promise2 -
如果
then是函数,将x作为函数的作用域this调用之。传递两个回调函数作为参数,第一个参数叫做resolvePromise,第二个参数叫做rejectPromise:-
如果
resolvePromise以值y为参数被调用,则运行[[Resolve]](promise2, y) -
如果
rejectPromise以拒因r为参数被调用,则以拒因r拒绝promise2 -
如果
resolvePromise和rejectPromise均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用这里主要是为了更好的契合
then方法中onFulfilled和onRejected仅会执行其中一个和仅执行一次
-
-
如果调用
then方法抛出了异常e:- 如果
resolvePromise或rejectPromise已经被调用,则忽略之 - 否则以
e为拒因拒绝promise2
- 如果
-
如果
then不是函数,以x为参数解决promise2
-
-
如果
x不为对象或者函数,以x为参数解决promise2
const state = {
pending: 'pending',
fulfilled: 'fulfilled',
rejected: 'rejected',
}
//4.1 Promise 解决过程
function promiseResolve(promise2, x, resolve, reject) {
//5.1 如果 `promise2` 和 `x` 指向同一对象,以 `TypeError` 为拒因拒绝 `promise2`
if (promise2 === x) {
reject(TypeError("promise2和x为同一对象!"))
}
//3.0 如果 `x` 是一个对象或者函数
else if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
let isRun = false
try {
// 5.1 把 `x.then` 赋值给 `then`
const then = x.then
//5.3 如果 `then` 是函数,将 `x` 作为函数的作用域 `this` 调用之。传递两个回调函数作为参数,第一个参数叫做 `resolvePromise` ,第二个参数叫做 `rejectPromise`
if (typeof then === 'function') {
then.call(x, (y) => {
// 5.3.3 如果 `resolvePromise` 和 `rejectPromise` 均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用
if (isRun) return
isRun = true
//5.3.1 如果 `resolvePromise` 以值 `y` 为参数被调用,则运行 `[[Resolve]](promise2, y)`
promiseResolve(promise2, y, resolve, reject)
}, (r) => {
// 5.3.3 如果 `resolvePromise` 和 `rejectPromise` 均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用
if (isRun) return
isRun = true
//5.3.2 如果 `rejectPromise` 以拒因 `r` 为参数被调用,则以拒因 `r` 拒绝 `promise2`
reject(r)
})
} else {
// 5.3.4 如果 `then` 不是函数,以 `x` 为参数解决 `promise2`
resolve(x)
}
} catch (error) {
//5.3.4 如果调用 `then` 方法抛出了异常 `e`:如果 `resolvePromise` 或 `rejectPromise` 已经被调用,则忽略之.否则以 `e` 为拒因拒绝 `promise2`
if (isRun) return
isRun = true
//3.2 如果取 `x.then` 的值时抛出错误 `e` ,则以 `e` 为拒因拒绝 `promise2`
reject(error)
}
} else {
//5.4 如果 `x` 不为对象或者函数,以 `x` 为参数解决 `promise2`
resolve(x)
}
}
//1.1 Promise 是一个构造函数(ES6 中使用类)
class MyPromise {
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
constructor(executor) {
// 2.1 Promise 需要一个状态值,初始值为pending
this.state = state.pending
// 3.2 记录promise 的终值/拒因
this.value = undefined
this.reason = undefined
//3.5 then 方法可以被同一个 promise 调用多次 需按照其注册顺序依次回调
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
//1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`,并且均能够接收参数
const resolve = (value) => {
//2.2 执行函数调用 resolve 时改变状态 能且只能: pending-->fulfilled
if (this.state === state.pending) {
this.state = state.fulfilled
this.value = value
//3.5 当 promise 解决后,所有的 `onFulfilled` 需按照其注册顺序依次回调
this.onFulfilledCallbacks && this.onFulfilledCallbacks.forEach(onFulfilled => {
onFulfilled(value)
});
}
}
const reject = (reason) => {
//2.2 执行函数调用 reject 时改变状态 能且只能: pending-->rejected
if (this.state === state.pending) {
this.state = state.rejected
this.reason = reason
//3.5 当 promise 拒绝后,所有的 `onRejected` 需按照其注册顺序依次回调
this.onRejectedCallbacks && this.onRejectedCallbacks.forEach(onRejected => {
onRejected(reason)
})
}
}
// 1.2 new Promise 时传入一个执行函数,并且执行函数是立即执行的
try { //防止出错放入try
executor(resolve, reject) //1.3执行函数接收两个参数 `resolve 函数 和 reject 函数`
} catch (error) {
throw error
}
}
// 1.4Promise 的实例上有一个 `then` 方法, `then` 方法接收两个参数
then(onFulfilled, onRejected) {
// 4.0 then 方法必须返回一个 Promise 对象
const promise2 = new MyPromise((resolve, reject) => {
// 3.2 onFulfilled, onRejected 在解决后其必须被调用 并且只能在解决后被调用
// 两个if是为了保证 new MyPromise里是同步代码时执行 else 是为了保证异步时执行
if (this.state === state.fulfilled) {
// 3.1 如果 `onFulfilled` 不是函数,必须将其忽略
if (typeof onFulfilled === 'function') {
//3.3 并不是 promise 解决或者拒绝后就立即调用的,而是放到宏任务或微任务任务队列中,
//3.3 确保异步地执行并且应该是在 `then` 方法被调用后的新一轮事件循环的新执行栈中执行
queueMicrotask(() => {
try {
//4.1 如果 `onFulfilled` 为函数且返回一个值 `x` ,则运行 Promise 解决过程
const x = onFulfilled(this.value)
promiseResolve(promise2, x, resolve, reject)
} catch (error) {
//4.2 如果或者 `onFulfilled` 抛出一个异常 `e` ,则 `promise2` 必须拒绝并返回拒因 `e`
reject(error)
}
})
} else {
//4.3 如果 `onFulfilled` 不是函数且 `promise1` 已解决, `promise2` 必须解决并返回与 `promise1` 相同的值
resolve(this.value)
}
} else if (this.state === state.rejected) {
//3.1 `onRejected` 不是函数,必须将其忽略 这里是直接加入微任务队列
if (typeof onRejected === 'function') {
//3.3 并不是 promise 解决或者拒绝后就立即调用的,而是放到宏任务或微任务任务队列中,
//3.3 确保异步地执行并且应该是在 `then` 方法被调用后的新一轮事件循环的新执行栈中执行
queueMicrotask(() => {
try {
//4.1 如果 `onRejected` 为函数且返回一个值 `x` ,则运行 Promise 解决过程
const x = onRejected(this.reason)
promiseResolve(promise2, x, resolve, reject)
} catch (error) {
//4.2 如果或者 `onRejected` 抛出一个异常 `e` ,则 `promise2` 必须拒绝并返回拒因 `e`
reject(error)
}
})
} else {
//4.4 如果 `onRejected` 不是函数且 `promise1` 已拒绝, `promise2` 必须拒绝并返回与 `promise1` 相同的拒因
reject(this.reason)
}
} else { //这里是加入待执行队列,当状态改变时才执行
// 3.2 & 3.3 & 3,5 记录下onFulfilled, onRejected以备执行
this.onFulfilledCallbacks.push(value => {
queueMicrotask(() => {
if (typeof onFulfilled === 'function') { //这里放进来是为了在执行时才判断是否为函数
try {
//4.1 如果 `onFulfilled` 为函数且返回一个值 `x` ,则运行 Promise 解决过程
const x = onFulfilled(value)
promiseResolve(promise2, x, resolve, reject)
} catch (error) {
//4.2 如果 `onFulfilled`抛出一个异常 `e` ,则 `promise2` 必须拒绝并返回拒因 `e`
reject(error)
}
} else {
//4.3 如果 `onFulfilled` 不是函数且 `promise1` 已解决, `promise2` 必须解决并返回与 `promise1` 相同的值
resolve(value)
}
})
})
this.onRejectedCallbacks.push(reason => {
queueMicrotask(() => {
if (typeof onRejected === 'function') { //这里放进来是为了在执行时才判断是否为函数
try {
//4.1 如果 `onRejected` 为函数且返回一个值 `x` ,则运行 Promise 解决过程
const x = onRejected(reason)
promiseResolve(promise2, x, resolve, reject)
} catch (error) {
//4.2 如果 `onRejected`抛出一个异常 `e` ,则 `promise2` 必须拒绝并返回拒因 `e`
reject(error)
}
} else {
//4.4 如果 `onRejected` 不是函数且 `promise1` 已拒绝, `promise2` 必须拒绝并返回与 `promise1` 相同的拒因
reject(reason)
}
})
})
}
})
return promise2
}
}
优化代码
3.1 统一处理 onFulfilled 和 onRejected 函数
- 当
onFulfilled不是函数时,最终是解决 promise2 并传递和 promise1 相同的值,因此完全可以处理成一个传递值得函数即可:value => value - 当
onRejected不是函数时,最终是拒绝 promise2 并传递和 promise1 相同的拒因,因此完全可以处理成一个抛出错误的函数即可:reason => { throw reason }
3.2 封装 promise 解决或拒绝后的执行逻辑
const state = {
pending: 'pending',
fulfilled: 'fulfilled',
rejected: 'rejected',
}
function promiseResolve(promise2, x, resolve, reject) {
if (promise2 === x) {
reject(TypeError("promise2和x为同一对象!"))
} else if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
let isRun = false
try {
const then = x.then
if (typeof then === 'function') {
then.call(x, (y) => {
if (isRun) return
isRun = true
promiseResolve(promise2, y, resolve, reject)
}, (r) => {
if (isRun) return
isRun = true
reject(r)
})
} else {
resolve(x)
}
} catch (error) {
if (isRun) return
isRun = true
reject(error)
}
} else {
resolve(x)
}
}
class MyPromise {
constructor(executor) {
this.state = state.pending
this.value = undefined
this.reason = undefined
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
const resolve = (value) => {
if (this.state === state.pending) {
this.state = state.fulfilled
this.value = value
this.onFulfilledCallbacks && this.onFulfilledCallbacks.forEach(onFulfilled => {
onFulfilled(value)
});
}
}
const reject = (reason) => {
if (this.state === state.pending) {
this.state = state.rejected
this.reason = reason
this.onRejectedCallbacks && this.onRejectedCallbacks.forEach(onRejected => {
onRejected(reason)
})
}
}
try {
executor(resolve, reject)
} catch (error) {
throw error
}
}
then(onFulfilledp, onRejectedp) {
//直接处理成函数,这样就不用判断是否为函数了
const onFulfilled = typeof onFulfilledp === 'function' ? onFulfilledp : value => value;
const onRejected = typeof onRejectedp === 'function' ? onRejectedp : reason => { throw reason };
//封装相同的逻辑
const promise2 = new MyPromise((resolve, reject) => {
const encloseFulRej = (OnFulfilledOrOnRejected, parma) => {
queueMicrotask(() => {
try {
const x = OnFulfilledOrOnRejected(parma)
promiseResolve(promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
}
if (this.state === state.fulfilled) {
encloseFulRej(onFulfilled, this.value)
} else if (this.state === state.rejected) {
encloseFulRej(onRejected, this.reason)
} else {
this.onFulfilledCallbacks.push(value => {
encloseFulRej(onFulfilled, value)
})
this.onRejectedCallbacks.push(reason => {
encloseFulRej(onRejected, reason)
})
}
})
return promise2
}
}
实现更多功能
Promise.catch(onRejected)
-
catch方法接受一个参数onRejected,这是一个在Promise被拒绝时调用的回调函数 -
catch方法实际上是then方法的一个语法糖。它调用then方法,并将onFulfilled参数设置为undefined或null,将onRejected参数设置为传入的onRejected回调函数。 -
catch方法返回一个新的Promise,这个新的Promise的状态和值取决于then方法的返回值
catch(onRejected) {
return this.then(null, onRejected);
}
Promise.finally(onRejected)
-
finally方法接受一个参数onFinally,这是一个在Promise结束时调用的回调函数。这个回调函数不接受任何参数。 -
finally方法内部调用then方法,并将onFulfilled和onRejected参数都用MyPromise.resolve().then()包裹,然后设置为 then的两个参数,这么做的目的是不影响原始Promise的结果,使后续的promis链能正常执行 -
finally方法返回一个新的Promise,这个新的Promise的状态和值取决于then方法的返回值。
finally(onFinally) {
return this.then(
value => {
return MyPromise.resolve(onFinally()).then(() => value);
},
reason => {
return MyPromise.resolve(onFinally()).then(() => { throw reason; });
}
);
}
Promise.resolve(value)
-
resolve方法接受一个参数value,这个参数可以是任何值,包括另一个Promise对象。 -
如果
value本身就是一个Promise对象,则调用then方法。 -
如果
value不是Promise对象,创建一个新的Promise对象,并立即解析为该value。 -
返回一个新的
Promise对象,其状态为fulfilled,值为传入的value。
static resolve(value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
Promise.all(iterable)
-
参数检查:
- 检查传入的参数是否为可迭代对象(如数组)。如果不是,抛出一个
TypeError。 - 这一步确保传入的参数是有效的可迭代对象。
- 检查传入的参数是否为可迭代对象(如数组)。如果不是,抛出一个
-
初始化:
- 创建一个新的
MyPromise对象,返回这个新的 Promise。 - 初始化一个结果数组
results用于存储每个 Promise 的结果。 - 初始化一个计数器
count用于记录传入的 Promise 数量。 - 初始化一个计数器
resolvedCount用于记录已经解决的 Promise 数量。
- 创建一个新的
-
遍历传入的 Promise:
- 使用迭代器遍历传入的可迭代对象中的每个 Promise。
- 对于每个 Promise,记录其索引
index和增加计数器count。
-
处理每个 Promise:
-
如果当前项不是
MyPromise实例,则将其视为已解决的 Promise,并直接将其结果存入results数组中,同时增加resolvedCount。 -
如果当前项是MyPromise
实例,则使用then方法处理其成功和失败情况。
- 成功时,将结果存入
results数组,并增加resolvedCount。如果resolvedCount等于count,则表示所有 Promise 都已成功解决,调用resolve(results)返回结果数组。 - 失败时,直接调用
reject(reason)返回失败的原因。
- 成功时,将结果存入
-
-
处理空数组的情况:
- 如果传入的可迭代对象为空(即
count为 0),直接调用resolve([])返回一个空数组。
- 如果传入的可迭代对象为空(即
static all(iterable) {
// 1.检查是否为可迭代对象
if (!iterable || typeof iterable[Symbol.iterator] !== 'function') {
throw TypeError('object is not iterable (cannot read property Symbol(Symbol.iterator))');
}
//2.1 创建一个新的 MyPromise 对象,返回这个新的 Promise。
return new MyPromise((resolve, reject) => {
const results = [];//2.2//初始化一个结果数组 results 用于存储每个 Promise 的结果。
let count = 0; //2.3//初始化一个计数器 count 用于记录传入的 Promise 数量。
let resolvedCount = 0;//2.4//初始化一个计数器 resolvedCount 用于记录已经解决的 Promise 数量。
//3.1 遍历迭代器
const iterator = iterable[Symbol.iterator]();
let result;
while (!(result = iterator.next()).done) {
const promise = result.value;
const index = count;
count++;
//4.1 如果不是 Promise,则将其视为已解决的 Promise
if (!(promise instanceof MyPromise)) {
results[index] = promise;
resolvedCount++;
if (resolvedCount === count) {
resolve(results);
}
continue;
}
//4.2 处理 Promise 的成功和失败情况
promise.then(
(value) => {
results[index] = value;
resolvedCount++;
if (resolvedCount === count) {
resolve(results);
}
},
(reason) => {
reject(reason);
}
);
}
//5.0 如果没有 Promise,直接 resolve 空数组
if (count === 0) {
resolve([]);
}
});
}
Promise. allsettled(iterable)
-
参数检查:
- 检查传入的参数是否为可迭代对象(如数组)。如果不是,抛出一个
TypeError。
- 检查传入的参数是否为可迭代对象(如数组)。如果不是,抛出一个
-
初始化:
- 创建一个新的
MyPromise对象,返回这个新的 Promise。 - 初始化一个结果数组
results用于存储每个 Promise 的结果。 - 初始化一个计数器
count用于记录传入的 Promise 数量。 - 初始化一个计数器
settledCount用于记录已经结束的 Promise 数量。
- 创建一个新的
-
遍历传入的 Promise:
- 使用迭代器遍历传入的可迭代对象中的每个 Promise。
- 对于每个 Promise,记录其索引
index和增加计数器count。
-
处理每个 Promise:
-
使用then方法处理每个 Promise 的成功和失败情况。
-
成功时,将结果以
{ status: 'fulfilled', value: value }的形式存入results数组,并增加settledCount。 -
失败时,将结果以
{ status: 'rejected', reason: reason }的形式存入results数组,并增加settledCount。 -
每当一个 Promise 结束时,检查
settledCount是否等于count,如果是,则表示所有 Promise 都已结束,调用resolve(results)返回结果数组。
-
-
处理空数组的情况:
- 如果传入的可迭代对象为空(即
count为 0),直接调用resolve([])返回一个空数组。
static allSettled() {
// 1. 检查是否为可迭代对象
if (!iterable || typeof iterable[Symbol.iterator] !== 'function') {
throw TypeError('object is not iterable (cannot read property Symbol(Symbol.iterator))');
}
// 2.1 创建一个新的 MyPromise 对象,返回这个新的 Promise。
return new MyPromise((resolve, reject) => {
const results = []; // 2.2 初始化一个结果数组 results 用于存储每个 Promise 的结果。
let count = 0; // 2.3 初始化一个计数器 count 用于记录传入的 Promise 数量。
let settledCount = 0; // 2.4 初始化一个计数器 settledCount 用于记录已经结束的 Promise 数量。
// 3.1 遍历迭代器
const iterator = iterable[Symbol.iterator]();
let result;
while (!(result = iterator.next()).done) {
const promise = result.value;
const index = count;
count++;
// 4. 处理 Promise 的成功和失败情况
MyPromise.resolve(promise).then(
(value) => {
results[index] = { status: 'fulfilled', value: value };
settledCount++;
if (settledCount === count) {
resolve(results);
}
},
(reason) => {
results[index] = { status: 'rejected', reason: reason };
settledCount++;
if (settledCount === count) {
resolve(results);
}
}
);
}
// 5.0 如果没有 Promise,直接 resolve 空数组
if (count === 0) {
resolve([]);
}
});
}
Promise.any(iterable)
-
参数检查:
- 检查传入的参数是否为可迭代对象(如数组)。如果不是,抛出一个
TypeError。
- 检查传入的参数是否为可迭代对象(如数组)。如果不是,抛出一个
-
初始化:
- 创建一个新的
MyPromise对象,返回这个新的 Promise。 - 初始化一个计数器
count用于记录传入的 Promise 数量。 - 初始化一个数组
rejectionReasons用于存储每个 Promise 的失败原因。 - 初始化一个计数器
rejectedCount用于记录已经失败的 Promise 数量。
- 创建一个新的
-
遍历传入的 Promise:
- 使用迭代器遍历传入的可迭代对象中的每个 Promise。
- 对于每个 Promise,记录其索引
index和增加计数器count。
-
处理每个 Promise:
- 使用then方法处理每个 Promise 的成功和失败情况。
- 成功时,直接调用
resolve(value)返回该 Promise 的值。 - 失败时,将失败原因存入
rejectionReasons数组,并增加rejectedCount。如果rejectedCount等于count,则表示所有 Promise 都已失败,调用reject并传入一个AggregateError对象,包含所有失败的原因。
-
处理空数组的情况:
- 如果传入的可迭代对象为空(即
count为 0),直接调用reject并传入一个AggregateError对象,表示没有 Promise 可以解决。
- 如果传入的可迭代对象为空(即
static any(iterable) {
// 1. 检查是否为可迭代对象
if (!iterable || typeof iterable[Symbol.iterator] !== 'function') {
throw TypeError('object is not iterable (cannot read property Symbol(Symbol.iterator))');
}
// 2.1 创建一个新的 MyPromise 对象,返回这个新的 Promise。
return new MyPromise((resolve, reject) => {
const rejectionReasons = []; // 2.2 初始化一个数组 rejectionReasons 用于存储每个 Promise 的失败原因。
let count = 0; // 2.3 初始化一个计数器 count 用于记录传入的 Promise 数量。
let rejectedCount = 0; // 2.4 初始化一个计数器 rejectedCount 用于记录已经失败的 Promise 数量。
// 3.1 遍历迭代器
const iterator = iterable[Symbol.iterator]();
let result;
while (!(result = iterator.next()).done) {
const promise = result.value;
const index = count;
count++;
// 4. 处理 Promise 的成功和失败情况
MyPromise.resolve(promise).then(
(value) => {
resolve(value);
},
(reason) => {
rejectionReasons[index] = reason;
rejectedCount++;
if (rejectedCount === count) {
reject(new AggregateError(rejectionReasons, 'All promises were rejected'));
}
}
);
}
// 5.0 如果没有 Promise,直接 reject 并传入一个 AggregateError 对象
if (count === 0) {
reject(new AggregateError([], 'All promises were rejected'));
}
});
}
Promise.race(iterable)
-
参数检查:
- 检查传入的参数是否为可迭代对象(如数组)。如果不是,抛出一个
TypeError。
- 检查传入的参数是否为可迭代对象(如数组)。如果不是,抛出一个
-
初始化:
- 创建一个新的
MyPromise对象,返回这个新的 Promise。
- 创建一个新的
-
遍历传入的 Promise:
- 使用迭代器遍历传入的可迭代对象中的每个 Promise。
- 对于每个 Promise,记录其索引
index。
-
处理每个 Promise:
- 使用then方法处理每个 Promise 的成功和失败情况。
- 成功时,直接调用
resolve(value)返回该 Promise 的值。 - 失败时,直接调用
reject(reason)返回该 Promise 的失败原因。
-
处理空数组的情况:
- 如果传入的可迭代对象为空(即没有 Promise),返回一个新的
MyPromise对象,该对象永远不会被解决或拒绝。
- 如果传入的可迭代对象为空(即没有 Promise),返回一个新的
static race(iterable) {
// 1. 检查是否为可迭代对象
if (!iterable || typeof iterable[Symbol.iterator] !== 'function') {
throw TypeError('object is not iterable (cannot read property Symbol(Symbol.iterator))');
}
// 2.1 创建一个新的 MyPromise 对象,返回这个新的 Promise。
return new MyPromise((resolve, reject) => {
// 3.1 遍历迭代器
const iterator = iterable[Symbol.iterator]();
let result;
while (!(result = iterator.next()).done) {
const promise = result.value;
// 4. 处理 Promise 的成功和失败情况
MyPromise.resolve(promise).then(
(value) => {
resolve(value);
},
(reason) => {
reject(reason);
}
);
}
});
}
完整实现:
const state = {
pending: 'pending',
fulfilled: 'fulfilled',
rejected: 'rejected',
}
function promiseResolve(promise2, x, resolve, reject) {
if (promise2 === x) {
reject(TypeError("promise2和x为同一对象!"))
} else if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
let isRun = false
try {
const then = x.then
if (typeof then === 'function') {
then.call(x, (y) => {
if (isRun) return
isRun = true
promiseResolve(promise2, y, resolve, reject)
}, (r) => {
if (isRun) return
isRun = true
reject(r)
})
} else {
resolve(x)
}
} catch (error) {
if (isRun) return
isRun = true
reject(error)
}
} else {
resolve(x)
}
}
class MyPromise {
constructor(executor) {
this.state = state.pending
this.value = undefined
this.reason = undefined
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
const resolve = (value) => {
if (this.state === state.pending) {
this.state = state.fulfilled
this.value = value
this.onFulfilledCallbacks && this.onFulfilledCallbacks.forEach(onFulfilled => {
onFulfilled(value)
});
}
}
const reject = (reason) => {
if (this.state === state.pending) {
this.state = state.rejected
this.reason = reason
this.onRejectedCallbacks && this.onRejectedCallbacks.forEach(onRejected => {
onRejected(reason)
})
}
}
try {
executor(resolve, reject)
} catch (error) {
throw error
}
}
then(onFulfilledp, onRejectedp) {
//直接处理成函数,这样就不用判断是否为函数了
const onFulfilled = typeof onFulfilledp === 'function' ? onFulfilledp : value => value;
const onRejected = typeof onRejectedp === 'function' ? onRejectedp : reason => { throw reason };
//封装相同的逻辑
const promise2 = new MyPromise((resolve, reject) => {
const encloseFulRej = (OnFulfilledOrOnRejected, parma) => {
queueMicrotask(() => {
try {
const x = OnFulfilledOrOnRejected(parma)
promiseResolve(promise2, x, resolve, reject)
} catch (error) {
reject(error)
}
})
}
if (this.state === state.fulfilled) {
encloseFulRej(onFulfilled, this.value)
} else if (this.state === state.rejected) {
encloseFulRej(onRejected, this.reason)
} else {
this.onFulfilledCallbacks.push(value => {
encloseFulRej(onFulfilled, value)
})
this.onRejectedCallbacks.push(reason => {
encloseFulRej(onRejected, reason)
})
}
})
return promise2
}
// 添加一个回调函数,在 Promise 失败时执行,等价于 then(null, onRejected)。
catch(onRejected) {
return this.then(null, onRejected);
}
// finally 方法是 Promise 对象的一个实例方法,用于在 Promise 结束时(无论是成功还是失败)执行某些操作
finally(onFinally) {
return this.then(
value => {
return MyPromise.resolve(onFinally()).then(() => value);
},
reason => {
return MyPromise.resolve(onFinally()).then(() => { throw reason; });
}
);
}
// Promise.resolve(value):返回一个解析为给定值的 Promise。如果该值本身就是一个 Promise,则直接返回该 Promise。
static resolve(value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
// Promise.reject(reason):返回一个拒绝的 Promise,并带有给定的原因。
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
// Promise.all(iterable):返回一个新的 Promise,当所有传入的 Promise 都成功时,返回一个包含所有结果的数组;如果任何一个 Promise 失败,则返回该失败的 Promise 的结果。
static all(iterable) {
// 1.检查是否为可迭代对象
if (!iterable || typeof iterable[Symbol.iterator] !== 'function') {
throw TypeError('object is not iterable (cannot read property Symbol(Symbol.iterator))');
}
//2.1 创建一个新的 MyPromise 对象,返回这个新的 Promise。
return new MyPromise((resolve, reject) => {
const results = [];//2.2//初始化一个结果数组 results 用于存储每个 Promise 的结果。
let count = 0; //2.3//初始化一个计数器 count 用于记录传入的 Promise 数量。
let resolvedCount = 0;//2.4//初始化一个计数器 resolvedCount 用于记录已经解决的 Promise 数量。
//3.1 遍历迭代器
const iterator = iterable[Symbol.iterator]();
let result;
while (!(result = iterator.next()).done) {
const promise = result.value;
const index = count;
count++;
//4.1 如果不是 Promise,则将其视为已解决的 Promise
if (!(promise instanceof MyPromise)) {
results[index] = promise;
resolvedCount++;
if (resolvedCount === count) {
resolve(results);
}
continue;
}
//4.2 处理 Promise 的成功和失败情况
promise.then(
(value) => {
results[index] = value;
resolvedCount++;
if (resolvedCount === count) {
resolve(results);
}
},
(reason) => {
reject(reason);
}
);
}
//5.0 如果没有 Promise,直接 resolve 空数组
if (count === 0) {
resolve([]);
}
});
}
// Promise.allSettled(iterable):返回一个新的 Promise,当所有传入的 Promise 都结束时(无论是成功还是失败),返回一个包含所有结果的对象数组。
static allSettled(iterable) {
// 1. 检查是否为可迭代对象
if (!iterable || typeof iterable[Symbol.iterator] !== 'function') {
throw TypeError('object is not iterable (cannot read property Symbol(Symbol.iterator))');
}
// 2.1 创建一个新的 MyPromise 对象,返回这个新的 Promise。
return new MyPromise((resolve, reject) => {
const results = []; // 2.2 初始化一个结果数组 results 用于存储每个 Promise 的结果。
let count = 0; // 2.3 初始化一个计数器 count 用于记录传入的 Promise 数量。
let settledCount = 0; // 2.4 初始化一个计数器 settledCount 用于记录已经结束的 Promise 数量。
// 3.1 遍历迭代器
const iterator = iterable[Symbol.iterator]();
let result;
while (!(result = iterator.next()).done) {
const promise = result.value;
const index = count;
count++;
// 4. 处理 Promise 的成功和失败情况
MyPromise.resolve(promise).then(
(value) => {
results[index] = { status: 'fulfilled', value: value };
settledCount++;
if (settledCount === count) {
resolve(results);
}
},
(reason) => {
results[index] = { status: 'rejected', reason: reason };
settledCount++;
if (settledCount === count) {
resolve(results);
}
}
);
}
// 5.0 如果没有 Promise,直接 resolve 空数组
if (count === 0) {
resolve([]);
}
});
}
// Promise.any(iterable):返回一个新的 Promise。这个新的 Promise 在传入的任意一个 Promise 成功时立即解决,并返回该 Promise 的值。如果所有传入的 Promise 都失败,则返回一个聚合错误
static any(iterable) {
// 1. 检查是否为可迭代对象
if (!iterable || typeof iterable[Symbol.iterator] !== 'function') {
throw TypeError('object is not iterable (cannot read property Symbol(Symbol.iterator))');
}
// 2.1 创建一个新的 MyPromise 对象,返回这个新的 Promise。
return new MyPromise((resolve, reject) => {
const rejectionReasons = []; // 2.2 初始化一个数组 rejectionReasons 用于存储每个 Promise 的失败原因。
let count = 0; // 2.3 初始化一个计数器 count 用于记录传入的 Promise 数量。
let rejectedCount = 0; // 2.4 初始化一个计数器 rejectedCount 用于记录已经失败的 Promise 数量。
// 3.1 遍历迭代器
const iterator = iterable[Symbol.iterator]();
let result;
while (!(result = iterator.next()).done) {
const promise = result.value;
const index = count;
count++;
// 4. 处理 Promise 的成功和失败情况
MyPromise.resolve(promise).then(
(value) => {
resolve(value);
},
(reason) => {
rejectionReasons[index] = reason;
rejectedCount++;
if (rejectedCount === count) {
reject(new AggregateError(rejectionReasons, 'All promises were rejected'));
}
}
);
}
// 5.0 如果没有 Promise,直接 reject 并传入一个 AggregateError 对象
if (count === 0) {
reject(new AggregateError([], 'All promises were rejected'));
}
});
}
// Promise.race(iterable):返回一个新的 Promise,当传入的任意一个 Promise 结束时(无论是成功还是失败),返回该 Promise 的结果。
static race(iterable) {
// 1. 检查是否为可迭代对象
if (!iterable || typeof iterable[Symbol.iterator] !== 'function') {
throw TypeError('object is not iterable (cannot read property Symbol(Symbol.iterator))');
}
// 2.1 创建一个新的 MyPromise 对象,返回这个新的 Promise。
return new MyPromise((resolve, reject) => {
// 3.1 遍历迭代器
const iterator = iterable[Symbol.iterator]();
let result;
while (!(result = iterator.next()).done) {
const promise = result.value;
// 4. 处理 Promise 的成功和失败情况
MyPromise.resolve(promise).then(
(value) => {
resolve(value);
},
(reason) => {
reject(reason);
}
);
}
});
}
}