手写Promise
class Prom {
static resolve(value) {
if (value && value.then) {
return value
}
return new Prom(resolve => {
resolve(value)
})
}
constructor(fn) {
this.value = ''
this.reason = ''
this.status = 'pending'
/* 目的:为了处理异步 */
this.resolvedFns = []
this.rejectedFns = []
const resolve = value => {
/* 使用setTimeout能保证前面的模拟同步都执行完 */
setTimeout(() => {
this.status = 'resolved'
this.value = value
this.resolvedFns.forEach(({ fn, resolve: res, reject: rej }) => {
res(fn(value))
})
})
}
const reject = reason => {
setTimeout(() => {
this.status = 'rejected'
this.reason = reason
this.rejectedFns.forEach(({ fn, resolve: res, reject: rej }) => {
rej(fn(value))
})
})
}
fn(resolve, reject)
}
then(fn) {
if (this.status == 'resolved') {
const result = fn(this.value)
return Prom.resolve(result)
}
if (this.status == 'pending') {
return new Prom((resolve, reject) => {
this.resolvedFns.push({ fn, resolve, reject })
})
}
}
catch(fn) {
if (this.status == 'rejected') {
const result = fn(this.value)
return Prom.reject(result)
}
if (this.status == 'pending') {
return new Prom((resolve, reject) => {
this.rejectedFns.push({ fn, resolve, reject })
})
}
}
}
new Prom((res, rej) => {
res(10)
})
.then(o => o * 10)
.then(o => o + 10)
.then(o => {
console.log(o) // 110
})
Promise.all
思路:和Promise.allSettled差不多 只是返回的状态并非是全部的
function promiseall(arr) {
return new Promise((res, rej) => {
const n = arr.length
let num = 0
const ans = new Array(n)
arr.forEach((item, index) => {
item
.then(data => {
ans[index] = data
num++
if (num == n) {
res(ans)
}
})
.catch(data => {
rej(data)
})
})
})
}
Promise.race
思路:直接对传入的Promise进行遍历执行 返回第一个执行完的结果
function myPromiseRace(promises) {
return new Promise((resolve, reject) => {
promises.forEach(item => {
item
.then(() => {
resolve(item)
})
.catch(() => {
reject(item)
})
})
})
}
Promise.allSettled
思路:只需要进行每次执行完的结果都保存到数组中,最后都执行完的话 直接进行返回
function myPromiseAllSettled(promises) {
const n = promises.length
let num = 0
const ans = []
return new Promise((resolve, reject) => {
for (let i = 0; i < n; i++) {
prpmises[i]
.then(() => {
num++
ans[i] = promises[i]
if (num == n) resolve(ans)
})
.catch(() => {
num++
ans[i] = promises[i]
if (num == n) resolve(ans)
})
}
})
}