說起Promise大家應該都耳熟能詳,我們今天來看下Promise的相關方法
有如下:
原型方法:then、catch、finally
靜態方法:resolve、reject、race、all、allSettled、any
手寫實現方法如下:
實現resolve方法
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物件。
參考 前端進階面試題詳細解答
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) 相同。
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 的回撥函式中不接收任何引數,它僅用於無論最終結果如何都要執行的情況。
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 決議(或拒絕)的值。
舉個?:
let p1=Promise.resolve(1)
let p2=Promise.reject(2)
let p3=Promise.resolve(3)
let p4=Promise.reject(4)
Promise.allSettled([p1,p2,p3,p4]).then(res=>{
console.log(res)
})
//返回了一個陣列
[{status: 'fulfilled', value: 1},
{status: 'rejected', reason: 2},
{status: 'fulfilled', value: 3},
{status: 'rejected', reason: 4}]
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 allSettled(promiseList) {
if (Array.isArray(promiseList)) {
return new MyPromise((resolve, reject) => {
let count = 0
let result = []
// 如果傳入的是一個空陣列,那麼就直接返回一個resolved的空陣列promise物件
if (promiseList.length === 0) {
return resolve(promiseList)
}
promiseList.forEach((item, index) => {
MyPromise.resolve(item).then(
(res) => {
count++
result[index] = {
status: MyPromise.FULFILLED,
value: res,
}
count === promiseList.length && resolve(result)
},
(error) => {
count++
result[index] = {
status: MyPromise.REJECTED,
reason: error,
}
count === promiseList.length && resolve(result)
}
)
})
})
} else {
throw TypeError('argument must be Array')
}
}
}
// 測試程式碼
const promise1 = MyPromise.resolve(3)
const promise2 = 1
const promises = [promise1, promise2]
MyPromise.allSettled(promises).then((results) =>
results.forEach((result) => console.log(result))
)
setTimeout(() => {
const p1 = MyPromise.resolve(3)
const p2 = new MyPromise((resolve, reject) =>
setTimeout(reject, 100, 'foo')
)
const ps = [p1, p2]
MyPromise.allSettled(ps).then((results) =>
results.forEach((result) => console.log(result))
)
}, 1000)
MyPromise.allSettled([]).then((results) => console.log(results))
//列印結果
(0) []
{status: 'fulfilled', value: 3}
{status: 'fulfilled', value: 1}
{status: 'fulfilled', value: 3}
{status: 'rejected', reason: 'foo'}
\
實現Promise.any
Promise.any() 接收一個Promise可迭代物件,只要其中的一個 promise 成功,就返回那個已經成功的 promise 。
如果可迭代物件中沒有一個 promise 成功(即所有的 promises 都失敗/拒絕),就返回一個失敗的 promise 和AggregateError型別的例項,它是 Error 的一個子類,用於把單一的錯誤集合在一起。
- 如果傳入的引數是一個空的可迭代物件,則返回一個 已失敗(already rejected) 狀態的 Promise。
- 如果傳入的引數不包含任何 promise,則返回一個 非同步完成 (asynchronously resolved)的 Promise。(將非Promise值,轉換為Promise並當做成功)
- 只要傳入的迭代物件中的任何一個 promise 變成成功(resolve)狀態,或者其中的所有的 promises 都失敗,那麼返回的 promise 就會 非同步地(當呼叫棧為空時) 變成成功/失敗(resolved/reject)狀態。(如果所有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)
}
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
//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 any(promiseList) {
if (Array.isArray(promiseList)) {
return new MyPromise((resolve, reject) => {
let count = 0
let errors = []
// 注意注意:如果傳入的引數是一個空的可迭代物件,則返回一個 已失敗(already rejected) 狀態的 Promise。
if (promiseList.length === 0) return reject(new AggregateError('All promises were rejected'));
promiseList.forEach((item, index) => {
MyPromise.resolve(item).then(
(res) => {
resolve(res)
},
(reason) => {
count++
errors.push(reason)
/**+ * 如果可迭代物件中沒有一個 promise 成功,就返回一個失敗的 promise 和AggregateError型別的例項,+ * AggregateError是 Error 的一個子類,用於把單一的錯誤集合在一起。+ */
count === promiseList.length &&
reject(new AggregateError(errors))
}
)
})
})
} else {
throw TypeError('argument must be Array')
}
}
}
// 測試程式碼
MyPromise.any([]).catch((e) => {
console.log(e)
})
const pErr = new Promise((resolve, reject) => {
reject('總是失敗')
})
const pSlow = new Promise((resolve, reject) => {
setTimeout(resolve, 500, '最終完成')
})
const pFast = new Promise((resolve, reject) => {
setTimeout(resolve, 100, '很快完成')
})
Promise.any([pErr, pSlow, pFast]).then((value) => {
console.log(value)
// 期望輸出: "很快完成"
})
const pErr1 = new MyPromise((resolve, reject) => {
reject('總是失敗')
})
const pErr2 = new MyPromise((resolve, reject) => {
reject('總是失敗')
})
const pErr3 = new MyPromise((resolve, reject) => {
reject('總是失敗')
})
MyPromise.any([pErr1, pErr2, pErr3]).catch((e) => {
console.log(e)
})
//列印結果
// AggregateError: All promises were rejected
// AggregateError: All promises were rejected
// 很快完成
實現race方法
Promise.race(iterable) 方法返回一個 promise,一旦迭代器中的某個promise解決或拒絕,返回的 promise就會解決或拒絕。
一個待定的 Promise 只要給定的迭代中的一個promise解決或拒絕,就採用第一個promise的值作為它的返回值,從而非同步地解析或拒絕(一旦堆疊為空)。
race 函式返回一個 Promise,它將與第一個傳遞的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失敗(rejects),這要取決於第一個完成的方式是兩個中的哪個。
- 如果傳的迭代是空的,則返回的 promise 將永遠等待。
- 如果迭代包含一個或多個非承諾值和/或已解決/拒絕的承諾,則 Promise.race 將解析為迭代中找到的第一個值。
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)
}
//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 race(promiseList) {
if (Array.isArray(promiseList)) {
return new MyPromise((resolve, reject) => {
// 注意注意:如果傳入的引數是一個空的可迭代物件,則永遠為pending狀態
if (promiseList.length > 0) {
promiseList.forEach((item, index) => {
/** * 如果迭代包含一個或多個非承諾值和/或已解決/拒絕的承諾, * 則 Promise.race 將解析為迭代中找到的第一個值。 */
MyPromise.resolve(item).then(resolve, reject)
})
}
})
} else {
throw TypeError('argument must be Array')
}
}
}
// 測試程式碼
/** * 驗證Promise.race()方法 */
// 陣列全是非Promise值,測試透過
let p1 = Promise.race([1, 3, 4])
setTimeout(() => {
console.log('p1 :>> ', p1) //1
})
// 空陣列,測試透過
let p2 = Promise.race([])
setTimeout(() => {
console.log('p2 :>> ', p2) //pengding
})
// p1 :>> Promise {<fulfilled>: 1}
// p2 :>> Promise {<pending>}
總結:
Promise方法 | 總結 | 傳遞[]陣列影響 |
---|---|---|
all() | 引數所有結果為成功才執行then方法返回結果,否則catch方法為第一個rejected的Promise | 返回一個已完成(already resolved)狀態的 Promise(resolve([])) |
allSettled() | 不管Promise的結果是否成功,都要等結果返回完畢之後執行then方法 | |
race() | 只要有一個Promise有了結果,就決定了最終新Promise的狀態 | 一直處於pending狀態 |
any() | 只要有一個Promise為成功,就會這個成功Promise的結果,如果所有Promise為失敗,那麼最終新Promise的狀態為rejected且報錯 | Promise的狀態為rejected且報錯(AggregateError) |
finally() | 不管Promise物件無論變成fulfilled還是reject狀態,最終都會被執行的程式碼 | - |