说起Promise大家应该都耳熟能详,我们今天来看下Promise的相关方法
有如下:
原型方法:then、catch、finally
静态方法:resolve、reject、race、all、allSettled、any
手写实现方法如下:
实现resolve方法
代码语言:javascript复制promise.resolve('123')实质上就是
new Promise(resolve=>
resolve('123')
})
Promise.resolve(value) 将给定的一个值转为Promise对象。
- 如果这个值是一个 promise ,那么将返回这个 promise ;
- 如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;
- 否则返回的promise将以此值完成,即以此值执行resolve()方法 (状态为fulfilled)。
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
//value 要解析为 Promise 对象的值
static resolve(value) {
//如果是
if (value instanceof MyPromise) {
return value
} else if (value && typeof value === 'object' && 'then' in value) {
return new MyPromise((resolve, reject) => {
value.then(resolve, reject)
})
}
return new MyPromise((resolve) => {
resolve(value)
})
}
}
const promise1 = MyPromise.resolve(123)
promise1.then((value) => {
console.log(value)
// expected output: 123
})
// Resolve一个thenable对象
var p1 = MyPromise.resolve({
then: function (onFulfill) {
onFulfill('Resolving')
},
})
console.log(p1 instanceof MyPromise) // true, 这是一个Promise对象
setTimeout(() => {
console.log('p1 :>> ', p1)
}, 1000)
p1.then(
function (v) {
console.log(v) // 输出"Resolving!"
},
function (e) {
// 不会被调用
}
)
// Thenable在callback之前抛出异常
// MyPromise rejects
var thenable = {
then: function (resolve) {
throw new TypeError('Throwing')
resolve('Resolving')
},
}
var p2 = MyPromise.resolve(thenable)
p2.then(
function (v) {
// 不会被调用
},
function (e) {
console.log(e) // TypeError: Throwing
}
)
更多面试题解答参见 前端手写面试题详细解答
实现reject方法
const p=Promise.reject('error')
相当于下方函数:
const p=new Promise(reject=>{
reject('11111')
})
Promise.reject()方法返回一个带有拒绝原因的Promise对象。
代码语言:javascript复制 class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
//error 要解析为 Promise reject的值
static reject(error) {
return new MyPromise((resolve, reject) => {
reject(error)
})
}
}
MyPromise.reject(new Error('fail')).then(
function () {
// not called
},
function (error) {
console.error(error) // Error: fail
}
)
实现Promise.prototype.catch方法
catch() 方法返回一个Promise,并且处理拒绝的情况,用于指定发生错误时的回调函数。
它的行为与调用Promise.prototype.then(undefined, onRejected) 相同。
代码语言:javascript复制class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
}
// 捕获异常
const p2 = new MyPromise(function (resolve, reject) {
throw new Error('test')
})
p2.catch(function (error) {
console.log(error) //Error: test
})
实现 Promise.prototype.finally
finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。
由于无法知道promise的最终状态,所以 finally 的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。
代码语言:text复制 class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
finally(callBack) {
return this.then(callBack, callBack)
}
}
// 捕获异常
let p1 = new MyPromise(function (resolve, reject) {
resolve(1)
}).finally(function () {
console.log('finally') // finally
})
实现 Promise.all
Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 输入的所有promise的resolve回调的结果是一个数组。
- Promise.all 等待所有都完成(或第一个失败)
- 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise
- 如果参数中包含非 promise 值,这些值将被忽略,但仍然会被放在返回数组中,如果 promise 完成的话 (也就是如果参数里的某值不是Promise,则需要原样返回在数组里)
- 在任何情况下,Promise.all 返回的 promise 的完成状态的结果都是一个数组,它包含所有的传入迭代参数对象的值(也包括非 promise 值)。
- 如果传入的 promise 中有一个失败(rejected),Promise.all 异步地将失败的那个结果给失败状态的回调函数,而不管其它 promise 是否完成
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
//value 要解析为 Promise 对象的值
static resolve(value) {
//如果是
if (value instanceof MyPromise) {
return value
} else if (value && typeof value === 'object' && 'then' in value) {
return new MyPromise((resolve, reject) => {
value.then(resolve, reject)
})
}
return new MyPromise((resolve) => {
resolve(value)
})
}
static all(promiseList) {
if (Array.isArray(promiseList)) {
return new MyPromise((resolve, reject) => {
if (promiseList.length === 0) {
resolve(promiseList)
}
let count = 0
let result = []
promiseList.forEach((item, index) => {
if (item instanceof MyPromise) {
MyPromise.resolve(item).then(
(res) => {
count
result[index] = res
count === promiseList.length && resolve(result)
},
(error) => {
reject(error)
}
)
} else {
count
result[index] = item
count === promiseList.length && resolve(result)
}
})
})
} else {
throw TypeError('argument must be Array')
}
}
}
// 捕获异常
const promise1 = MyPromise.resolve(3)
const promise2 = 42
const promise3 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(100)
})
})
MyPromise.all([promise1, promise2, promise3]).then((values) => {
console.log(values)
})
// [3, 42, 100]
实现Promise.allSettled
Promise.allSettled(iterable)方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。
- 当你有多个彼此不依赖的异步任务成功完成时,或者你总是想知道每个promise的结果时,通常使用它。
- 相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束。
参数 iterable 是一个可迭代的对象,例如Array,其中每个成员都是Promise。
对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。value(或 reason )反映了每个 promise 决议(或拒绝)的值。
举个