一直以来对Promise只是会用简单的方法,例如then,catch等,对于其余各种方法也只是简单了解,这次想要通过实现Promise来加深对Promise的使用
话不多说,直接开始,简单粗暴一步步来
Promise是一种用于处理异步操作的JS对象,可以通过链式调用的方式来处理操作的结果
使Promise可以更加优雅地处理异步代码,避免回调地狱的产生
通过示例来了解Promise的基本用法
const p = new Promise((resolve, reject) =>
{
resolve(1)
})
const p2 = p.then(res =>
{
console.log(res) // 1
throw 'xxx'
})
p2.catch(error =>
{
console.log(error); //xxx
})
new Promise
创建一个Promise实例对象,在构造函数中传入一个执行器函数,该函数接收两个参数
then方法
,可以指定操作成功时所要执行的回调函数 catch方法
,可以指定操作失败时候要执行的回调函数
catch方法
打印对应的错误信息 状态变化
resolve(1)
,会将p实例对象的状态由 Pending
转为 Fulfilled
状态,即由待定状态转为成功状态 Rejected
,p2实例的catch方法会根据此时p2实例的状态捕获错误信息xxx then方法
then
方法会根据实例的不同状态执行不同的处理方法 onFulfied
和 onRejected
,分别表示成功时和失败时的回调函数
then
方法会立即执行 onFulfilled
回调函数,并将操作结果作为参数传递给该函数。 then
方法会立即执行 onRejected
回调函数,并将拒绝原因(错误信息)作为参数传递给该函数。 const p = new Promise((resolve, reject) =>
{
resolve(1)
// reject('xxx')
})
p.then(res =>
{
console.log(res) // 1
}, error =>
{
console.log(error);
})
onRejected
回调函数(第二个参数的回调函数)是一致的,都是用于当实例对象为 Rejected
状态时候,执行对应的回调函数,并将错误信息作为参数传递给该函数
Promise.prototype.then(undefined, onRejected)
的一种简写形式 了解Promise的基本使用过后,那么就可以来一步步去实现一个Promise,先去实现Promise的核心功能*
MyPromise
类,接收执行器函数(resolve/reject)并执行 class MyPromise
{
// 1. 添加构造函数
constructor(func)
{
// 2. 定义resolve/reject
const resolve = (result) =>
{
console.log(result) //success
}
const reject = (result) =>
{
console.log(result)
}
// 3. 执行回调函数
func(resolve, reject)
}
}
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
// reject('error')
})
func
接收传入的回调函数 //1. 设置三种状态
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise
{
constructor(func)
{
//2. 设置result存储原因 /初始化状态
this.state = PENDING
this.result = undefined
const resolve = (result) =>
{
//3. 通过resolve/reject修改状态
//注意判断状态条件 使得状态不可逆
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
}
}
const reject = (result) =>
{
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
}
}
func(resolve, reject)
}
}
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
reject('error')
})
注意状态的不可逆
,状态只能由pending -> fulfilled或者pending -> rejected,不可以从fulfilled -> rejected,条件判断一下, 即便resolve,reject都执行了,实例状态还是由第一个执行的函数改变
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
reject('error')
})
image-20231010132809495
class MyPromise
{
constructor(func)
{
//...
}
// 1. 添加实例方法
then (onFulfilled, onRejected)
{
// 2. 参数判断
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : x => { throw x }
// 2.1 执行成功回调
// 2.2 执行失败回调
if (this.state === FULFILLED) {
onFulfilled(this.result)
} else if (this.state === REJECTED) {
onRejected(this.result)
}
}
}
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
// reject('error')
})
p.then(res =>
{
console.log('p1:', res) // p1: success
})
成功的回调函数onFulfilled
,一个执行 失败的回调函数onRejected
typeof关键字
对参数类型进行判断,对于onFulfilled和onRejected,如果是回调函数都不做处理
mdn上这么说
:如果 onFulfilled
不是一个函数,则内部会被替换为一个 恒等函数( (x) => x
),它只是简单地将兑现值向前传递。 mdn上这么说
:如果 onRejected
不是一个函数,则内部会被替换为一个 抛出器函数( (x) => { throw x; }
),它会抛出它收到的拒绝原因 关键在于状态判断
:根据实例的状态来执行不同的回调函数
原因
(结果),传递给 then
方法的 参数
原因
(结果),传递给 then
方法的 参数
此时then方法为同步
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
})
p.then(res =>
{
console.log('p1:', res) //p1: success
})
const p = new MyPromise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('success')
}, 2000);
})
p.then(res =>
{
console.log('p1:', res)
})
image-20231010141014499
then方法是同步的
,它不会等到定时器结束才执行 先保存此时的回调和结果,等状态改变了再执行
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise
{
constructor(func)
{
//...
//保存成功的回调函数
this.onResolveCallbacks = []
//保存失败的回调函数
this.onRejectCallbacks = []
const resolve = (result) =>
{
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
//遍历执行保存的回调函数
this.onResolveCallbacks.forEach(fn => fn())
}
}
const reject = (result) =>
{
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
//遍历执行保存的回调函数
this.onRejectCallbacks.forEach(fn => fn())
}
}
func(resolve, reject)
}
then (onFulfilled, onRejected)
{
//...
if (this.state === FULFILLED) {
onFulfilled(this.result)
} else if (this.state === REJECTED) {
onRejected(this.result)
} else if (this.state === PENDING) {
//PENDING状态处理
this.onResolveCallbacks.push(() =>
{
onFulfilled(this.result)
})
this.onRejectCallbacks.push(() =>
{
onRejected(this.result)
})
}
}
}
const p = new MyPromise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('success')
}, 2000);
})
p.then(res =>
{
console.log('p1:', res) //p1: success
})
then方法
,由于我们用数组存储回调函数,即可以多次调用then方法了(非链式调用) const p = new MyPromise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('success')
}, 2000);
})
p.then(res =>
{
console.log('p1:', res)
})
p.then(res =>
{
console.log('p1:', res)
})
p.then(res =>
{
console.log('p1:', res)
})
在2.4中,我们实现了异步操作resolve/reject,能够成功处理对应结果,但当时的
then方法还是同步的
在Promise中
then方法是异步的
console.log(1);
const p1 = new Promise((resolve, reject) =>
{
resolve('success')
})
p1.then(res =>
{
console.log(res);
})
console.log(2);
执行结果为: 1 2 success
在MyPromise中
我们未对then方法的调用处理异步,此时还是同步的
console.log(1);
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
})
p.then(res =>
{
console.log('p1:', res)
})
console.log(2);
执行结果为:1 p1: success 2
使用settimeout处理异步
then (onFulfilled, onRejected)
{
//...
if (this.state === FULFILLED) {
setTimeout(() =>
{
onFulfilled(this.result)
}, 0);
} else if (this.state === REJECTED) {
setTimeout(() =>
{
onRejected(this.result)
}, 0);
} else if (this.state === PENDING) {
//执行回调
this.onResolveCallbacks.push(() =>
{
setTimeout(() =>
{
onFulfilled(this.result)
}, 0);
})
this.onRejectCallbacks.push(() =>
{
setTimeout(() =>
{
onRejected(this.result)
}, 0);
})
}
}
}
对于then的链式调用即需要实现很多关键点
返回一个新实例
then (onFulfilled, onRejected)
{
//...
const p2 = new MyPromise((resolve, reject) =>
{
//...
})
return p2
}
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
})
p.then(res =>
{
console.log('p1:', res)
return 1
}).then(res =>
{
console.log('p2:', res)
})
image-20231010144315841
可以链式调用then方法不会报错,但是第二个then方法明显无法第一个then方法的返回值,说明未对第一个实例的返回值进行处理
在Promise中,第一个then方法的返回值会传递给第二个链式调用的then方法的第一个回调函数的参数,即第二个then应该打印p2: 1
获取实例的返回值并对异常做出处理
then (onFulfilled, onRejected)
{
//...
const p2 = new MyPromise((resolve, reject) =>
{
if (this.state === FULFILLED) {
setTimeout(() =>
{
try {
const res = onFulfilled(this.result)
//将实例返回值传递给下一个then方法的onFulfilled回调函数
resolve(res)
} catch (error) {
//处理异常 将错误信息传递给下一个then方法的onRjected回调函数
reject(error)
}
}, 0);
}
//...
return p2
}
}
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
})
p.then(res =>
{
console.log('p1:', res)
return 1
}).then(res =>
{
console.log('p2:', res)
})
异常处理
,在then方法中,可能会抛出各种异常错误,因此需要利用try catch对异常做出处理
p.then(res =>
{
console.log('p1:', res)
throw 'xxxx'
return 1
}).then(res =>
{
console.log('p2:', res)
}, error =>
{
console.log('p2:', error)
})
image-20231010145657224
当返回值为MyPromise实例
then (onFulfilled, onRejected)
{
//...
const p2 = new MyPromise((resolve, reject) =>
{
if (this.state === FULFILLED) {
setTimeout(() =>
{
try {
const res = onFulfilled(this.result)
//1. 处理返回MyPromise实例
if (res instanceof MyPromise) {
res.then(res => resolve(res), error => reject(error))
} else {
//将实例返回值传递给下一个then方法的onFulfilled回调函数
resolve(res)
}
} catch (error) {
//处理异常 将错误信息传递给下一个then方法的onRjected回调函数
reject(error)
}
}, 0);
//...
}
})
return p2
}
}
const p = new MyPromise((resolve, reject) =>
{
resolve('success')
})
p.then(res =>
{
console.log('p1:', res)
return new MyPromise((resolve, reject) =>
{
resolve(2)
// reject('error')
})
}).then(res =>
{
console.log('p2:', res) //2
}, error =>
{
console.log('p2:', error)
})
instanceof
关键判断,res获取的返回值是否是MyPromise实例,如果是该实例 当返回值和接受返回值的实例一致(重复引用)
const p2 = new MyPromise((resolve, reject) =>
{
if (this.state === FULFILLED) {
setTimeout(() =>
{
try {
const res = onFulfilled(this.result)
// 处理重复引用
if (res === p2) {
throw new TypeError('Chaining cycle detected for promise #' )
}
//处理返回MyPromise实例
if (res instanceof MyPromise) {
res.then(res => resolve(res), error => reject(error))
} else {
//将实例返回值传递给下一个then方法的onFulfilled回调函数
resolve(res)
}
} catch (error) {
//处理异常 将错误信息传递给下一个then方法的onRjected回调函数
reject(error)
}
}, 0);
}
//...
})
return p2
const p2 = p.then(res =>
{
console.log('p1:', res)
return p2
})
p2.then(res =>
{
console.log('p2:', res)
}, error =>
{
console.log('p2:', error)
})
抽离函数
//封装函数 处理then方法
function resolvePromise (p2, res, resolve, reject)
{
//1. 重复引用 直接抛出错误
if (res === p2) {
throw new TypeError('Chaining cycle detected for promise #' )
}
//2. 返回值是MyPromise实例 利用then获取对应的resolve/reject的值
if (res instanceof MyPromise) {
res.then(res => resolve(res), error => reject(error))
} else {
//3.处理普通返回值
resolve(res)
}
}
//then方法 两个参数 onFulfilled, onRejected
then (onFulfilled, onRejected)
{
//...
const p2 = new MyPromise((resolve, reject) =>
{
if (this.state === FULFILLED) {
setTimeout(() =>
{
try {
//...
resolvePromise(p2, res, resolve, reject)
}
}, 0);
} else if (this.state === REJECTED) {
setTimeout(() =>
{
try {
//...
resolvePromise(p2, res, resolve, reject)
}
}, 0);
} else if (this.state === PENDING) {
this.onResolveCallbacks.push(() =>
{
setTimeout(() =>
{
try {
//...
resolvePromise(p2, res, resolve, reject)
}
}, 0);
})
this.onRejectCallbacks.push(() =>
{
setTimeout(() =>
{
try {
//...
resolvePromise(p2, res, resolve, reject)
}
}, 0);
})
}
})
return p2
}
核心功能实现之后,开始去实现,Promise实例上的方法
在之前的示例中有出现过catch方法的示例,也大体讲解了下catch方法与then方法之间的联系与关系
引用MDN中对catch方法的论述:
Promise
实例的 「catch()
」 方法用于注册一个在 promise 被拒绝时调用的函数。它会立即返回一个等效的Promise
对象,这可以允许你 链式调用其他 promise 的方法- 此方法是
Promise.prototype.then(undefined, onRejected)
的一种简写形式
总结一下
:
catch方法等同于then(undefined, onRejected)
catch()
方法用于捕获并处理 Promise 实例的拒绝状态。当 Promise 实例被拒绝时, catch()
方法会被调用,并传递拒绝的原因作为参数。 Promise实例
实现
参数(onRejected):一个在此 Promise 对象被拒绝时异步执行的函数。它的返回值将成为
catch()
返回的 Promise 对象的兑现值返回值:返回一个新Promise,新Promise在返回时总处于待定状态
catch (onRejected)
{
return this.then(undefined, onRejected)
}
const p = new MyPromise((resolve, reject) =>
{
reject('error')
})
p.then(res =>
{
console.log(res)
}).catch(error =>
{
console.log('p:', error); //p: error
})
Promise
实例的 「finally()
」 方法用于注册一个在 promise 敲定(兑现或拒绝)时调用的函数。它会立即返回一个等效的Promise
对象,这可以允许你链式调用其他 promise 方法。如果你想在 promise 敲定时进行一些处理或者清理,无论其结果如何,那么
finally()
方法会很有用。
总结一下
:
实现
参数(onFinally):回调函数
返回值:返回一个Promise实例
//finally方法
finally (onFinally)
{
return this.then(onFinally, onFinally)
}
const p = new MyPromise((resolve, reject) =>
{
// reject('error')
resolve('success')
})
p.then(res =>
{
console.log(res)
}).catch(error =>
{
console.log('p:', error);
}).finally(() =>
{
console.log(1); // success 1
})
Promise还提供了一些静态方法,是在构造函数上调用的,而不是在实例上调用的
「
Promise.resolve()
」 静态方法将给定的值转换为一个Promise
。如果该值本身就是一个 Promise,那么该 Promise 将被返回;如果该值是一个 thenable 对象,Promise.resolve()
将调用其then()
方法及其两个回调函数
Promise中的resolve方法
const p = Promise.resolve(1)
console.log(p);
p1 = Promise.resolve(p)
console.log(p1);
image-20231010203520862
思路
实现
参数(value):resolve方法接收的值,可能为MyPromise
返回值:MyPromise
static resolve (value)
{
//是一个MyPromise直接返回
if (value instanceof MyPromise) {
return value
}
//其余转化为MyPromise并返回
return new MyPromise(resolve =>
{
resolve(value)
})
}
即该实例状态直接被转为fulfilled
const p = MyPromise.resolve(1)
console.log(p);
const p1 = MyPromise.resolve(p)
console.log(p1);
image-20231010204409551
「
Promise.reject()
」 静态方法返回一个已拒绝(rejected)的Promise
对象,拒绝原因为给定的参数。
这个说的就很清楚
实现
参数(value):该
Promise
对象被拒绝的原因。返回值:Promise对象
static reject (value)
{
//直接返回一个Promise
return new MyPromise((undefined, reject) =>
{
reject(value)
})
}
const p = MyPromise.reject('error')
p.catch(error =>
{
console.log(error);
})
image-20231010204846632
「
Promise.race()
」 静态方法接受一个 promise 可迭代对象作为输入,并返回一个Promise
。这个返回的 promise 会随着第一个 promise 的敲定而敲定。
总结一下
在promise中
const p1 = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('p1')
}, 1000);
})
const p2 = 'p2'
const p3 = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
reject('p3')
}, 3000);
})
const p = Promise.race([p1, p2, p3])
p.then(res =>
{
console.log(res);
}).catch(error =>
{
console.log(error);
})
image-20231010205639328
思路
实现
参数(iterable):可迭代对象,例如数组
返回值:Promise
static race (promises)
{
//返回一个promsie
return new MyPromise((resolve, reject) =>
{
//如果参数不是一个数组直接抛出错误
if (!Array.isArray(promises)) {
return reject(new TypeError('Argument is not iterable'))
}
//遍历数组等待第一个敲定
promises.forEach(p =>
{
//由于p不一定是一个promise 先转化为promise
MyPromise.resolve(p).then(res =>
{
resolve(res)
}, error =>
{
reject(error)
})
})
})
}
「
Promise.all()
」 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个Promise
。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因。
总结一下
等所有的Promise实例全部都被兑现了
,并将兑现的值按照Promise传入数组的位置,依次存放到一个数组中 在Promise中
const p1 = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('p1')
}, 1000);
})
const p2 = 'p2'
const p3 = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('p3')
}, 3000);
})
const p = Promise.all([p1, p2, p3])
p.then(res =>
{
console.log(res);
}).catch(error =>
{
console.log(error);
})
image-20231010212126512
const p1 = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('p1')
}, 1000);
})
const p2 = 'p2'
const p3 = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
reject('p3')
}, 3000);
})
const p = Promise.all([p1, p2, p3])
p.then(res =>
{
console.log(res);
}).catch(error =>
{
console.log(error);
})
思路
通过索引记录兑现值在数组中的位置,保证跟参数中顺序一致
利用计数器计数,等待所有promise实例兑现
实现
static all (promises)
{
//返回一个promise
return new MyPromise((resolve, reject) =>
{
//不是数组抛出错误
if (!Array.isArray(promises)) {
return reject(new TypeError('Argument is not iterable'))
}
//空数组直接兑现
promises.length === 0 && resolve(promises)
const result = []
let count = 0
//foreach取出全部的promise
promises.forEach((p, index) =>
{
MyPromise.resolve(p).then(res =>
{
//记录结果
result[index] = res
//判断全部兑现 传递result
count++
count === promises.length && resolve(result)
}, error =>
{
//处理拒绝
reject(error)
})
})
})
}
通过result[index]索引记录对应的promise实例的兑现值
count计数器等所有的promise实例兑现,最后传递result数组
「
Promise.allSettled()
」 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的Promise
。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组
总结一下
在promise中
const p1 = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve('p1')
}, 1000);
})
const p2 = 'p2'
const p3 = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
reject('p3')
}, 3000);
})
const p = Promise.allSettled([p1, p2, p3])
p.then(res =>
{
console.log(res);
}).catch(error =>
{
console.log(error);
})
image-20231010213350301
实现
//settled方法
static allSettled (promises)
{
//返回promise
return new MyPromise((resolve, reject) =>
{
//判断数组
if (!Array.isArray(promises)) {
return reject(new TypeError('Argument is not iterable'))
}
// 为空
promises.length === 0 && resolve(promises)
const result = []
let count = 0
//遍历数组
promises.forEach((p, index) =>
{
MyPromise.resolve(p).then(res =>
{
//记录
result[index] = { status: FULFILLED, value: res }
count++
count === promises.length && resolve(result)
}, error =>
{
result[index] = { status: REJECTED, reason: error }
count++
count === promises.length && resolve(result)
})
})
})
}
「
Promise.any()
」 静态方法将一个 Promise 可迭代对象作为输入,并返回一个Promise
。当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的AggregateError
拒绝。
总结一下
实现
static any (promises)
{
// 1. 返回Promise,数组判断
return new MyPromise((resolve, reject) =>
{
if (!Array.isArray(promises)) {
return reject(new TypeError('Argument is not iterable'))
}
// 2. 空数组直接拒绝
promises.length === 0 && reject(new AggregateError(promises, 'All promises were rejected'))
// 3. 等待结果
const errors = []
let count = 0
promises.forEach((p, index) =>
{
MyPromise.resolve(p).then(res =>
{
// 3.1 第一个兑现
resolve(res)
}, err =>
{
// 3.2 全部拒绝
errors[index] = err
count++
count === promises.length && reject(new AggregateError(errors, 'All promises were rejected'))
})
})
})
}
}
function resolvePromise (p2, res, resolve, reject)
{
//1. 重复引用 直接抛出错误
if (res === p2) {
throw new TypeError('Chaining cycle detected for promise #' )
}
//2. 返回值是MyPromise实例 利用then获取对应的resolve/reject的值
if (res instanceof MyPromise) {
res.then(res => resolve(res), error => reject(error))
} else {
//3.处理普通返回值
resolve(res)
}
}
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise
{
constructor(func)
{
//初始状态pending
this.state = PENDING
//初始原因undefined
this.result = undefined
//保存成功的回调函数
this.onResolveCallbacks = []
//保存失败的回调函数
this.onRejectCallbacks = []
//更改状态
const resolve = (result) =>
{
if (this.state === PENDING) {
this.state = FULFILLED
this.result = result
//遍历执行保存的回调函数
this.onResolveCallbacks.forEach(fn => fn())
}
};
const reject = (result) =>
{
if (this.state === PENDING) {
this.state = REJECTED
this.result = result
//遍历执行保存的回调函数
this.onRejectCallbacks.forEach(fn => fn())
}
};
//捕获错误
try {
//执行函数
func(resolve, reject)
} catch (error) {
reject(error)
}
}
//then方法 两个参数 onFulfilled, onRejected
then (onFulfilled, onRejected)
{
//参数判断
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error }
//链式调用 返回新的promise实例
const p2 = new MyPromise((resolve, reject) =>
{
//根据状态执行成功失败的回调
if (this.state === FULFILLED) {
//并把失败的原因传递过去
setTimeout(() =>
{
//处理异常 调用reject并把异常传过去
try {
//res为p1的返回值 判断是否为promise
const res = onFulfilled(this.result)
resolvePromise(p2, res, resolve, reject)
} catch (error) {
reject(error)
}
}, 0);
} else if (this.state === REJECTED) {
setTimeout(() =>
{
//使用try catch捕获错误
try {
//获取p1返回值
const res = onRejected(this.result)
resolvePromise(p2, res, resolve, reject)
} catch (error) {
reject(error)
}
}, 0);
} else if (this.state === PENDING) {
//保存成功的回调
this.onResolveCallbacks.push(() =>
{
setTimeout(() =>
{
//处理异常
try {
//获取返回值
const res = onFulfilled(this.result)
resolvePromise(p2, res, resolve, reject)
} catch (error) {
reject(error)
}
}, 0);
})
//保存失败的回调
this.onRejectCallbacks.push(() =>
{
setTimeout(() =>
{
//处理异常
try {
//获取返回值
const res = onRejected(this.result)
resolvePromise(p2, res, resolve, reject)
} catch (error) {
reject(error)
}
}, 0);
})
}
})
//返回新的promise实例实现链式调用
return p2
}
//catch方法
catch (onRejected)
{
//调用then中的onRejected回调
return this.then(undefined, onRejected)
}
//finally方法
finally (onFinally)
{
return this.then(onFinally, onFinally)
}
//resolve方法
static resolve (value)
{
//是一个MyPromise直接返回
if (value instanceof MyPromise) {
return value
}
//其余转化为MyPromise并返回
return new MyPromise(resolve =>
{
resolve(value)
})
}
//reject方法
static reject (value)
{
//直接返回一个Promise
return new MyPromise((undefined, reject) =>
{
reject(value)
})
}
//race方法
static race (promises)
{
//返回一个promsie
return new MyPromise((resolve, reject) =>
{
//如果参数不是一个数组直接抛出错误
if (!Array.isArray(promises)) {
return reject(new TypeError('Argument is not iterable'))
}
//遍历数组等待第一个敲定
promises.forEach(p =>
{
//由于p不一定是一个promise 先转化为promise
MyPromise.resolve(p).then(res =>
{
resolve(res)
}, error =>
{
reject(error)
})
})
})
}
//all方法
static all (promises)
{
//返回一个promise
return new MyPromise((resolve, reject) =>
{
//不是数组抛出错误
if (!Array.isArray(promises)) {
return reject(new TypeError('Argument is not iterable'))
}
//空数组直接兑现
promises.length === 0 && resolve(promises)
const result = []
let count = 0
//foreach取出全部的promise
promises.forEach((p, index) =>
{
MyPromise.resolve(p).then(res =>
{
//记录结果
result[index] = res
//判断全部兑现 传递result
count++
count === promises.length && resolve(result)
}, error =>
{
//处理拒绝
reject(error)
})
})
})
}
//settled方法
static allSettled (promises)
{
//返回promise
return new MyPromise((resolve, reject) =>
{
//判断数组
if (!Array.isArray(promises)) {
return reject(new TypeError('Argument is not iterable'))
}
// 为空
promises.length === 0 && resolve(promises)
const result = []
let count = 0
//遍历数组
promises.forEach((p, index) =>
{
MyPromise.resolve(p).then(res =>
{
//记录
result[index] = { status: FULFILLED, value: res }
count++
count === promises.length && resolve(result)
}, error =>
{
result[index] = { status: REJECTED, reason: error }
count++
count === promises.length && resolve(result)
})
})
})
}
//any方法
static any (promises)
{
// 1. 返回Promise,数组判断
return new MyPromise((resolve, reject) =>
{
if (!Array.isArray(promises)) {
return reject(new TypeError('Argument is not iterable'))
}
// 2. 空数组直接拒绝
promises.length === 0 && reject(new AggregateError(promises, 'All promises were rejected'))
// 3. 等待结果
const errors = []
let count = 0
promises.forEach((p, index) =>
{
MyPromise.resolve(p).then(res =>
{
// 3.1 第一个兑现
resolve(res)
}, err =>
{
// 3.2 全部拒绝
errors[index] = err
count++
count === promises.length && reject(new AggregateError(errors, 'All promises were rejected'))
})
})
})
}
}
写完身心俱疲,但又有种知识充斥在脑海中的感觉,以前也只是了解会用promise的几种方法,也不了解其中方法的逻辑,
只有对其实现一下,才会对其更加的掌握,现在对promise有了更深的了解了,希望在以后使用promise的时候,调用其中的方法时候,能够想到其中的逻辑是怎么实现的,这样能更放心的去使用
参考文章:
本文由 mdnice 多平台发布