一、写在前面 本文主要总结Promise 的相关知识,主要分为两个部分,一个是对于Promsie 的api 使用。另一个是对于手写Promise 。完全解决面试问题。Promise 主要分为三种状态,一个是pendding ,一个是fulfillled ,另一个是rejected 。 二、Promise api的使用 2.1、promise的then方法
let promise = new Promise((resolve, reject) => {
resolve('hhhh')
}).then(res => {
console.log(res)
}).then(ret => {
console.log(ret)
})
let promise = new Promise((resolve, reject) => {
resolve("hhhh")
}).then(res => {
console.log(res)
return "next one"
}).then(res => {
console.log(res)
})
let promise = new Promise((resolve, reject) => {
resolve("hhhh")
}).then(res => {
console.log(res)
return new Promise((resolve, reject) => {
resolve("next one")
})
}).then(res => {
console.log(res)
})
let promise = new Promise((resolve, reject) => {
resolve("hhhh")
}).then(res => {
console.log(res)
return {
then(resolve, reject) {
resolve("next one")
}
}
}).then(res => {
console.log(res)
})
let promise = new Promise((resolve, reject) => {
resolve("hhhh")
})
promise.then(res => {
console.log(res + "第一个")
})
promise.then(res => {
console.log(res + "第二个")
})
2.2、catch方法
let promise = new Promise((resolve, reject) => {
throw new Error('err message')
})
promise.then(res => {
console.log(res)
}, err => {
console.log(err.name)
})
let promise = new Promise((resolve, reject) => {
resolve('大家好')
}).then(res => {
console.log(res)
return new Promise((resolve, reject) => {
reject('hhjhh')
})
}).catch(err => {
console.log(err)
})
let promise = new Promise((resolve, reject) => {
reject('message err')
})
promise.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
return 'hek'
}).then(ret => {
console.log(ret)
}).catch(err => {
console.log(err)
})
2.3、finnally方法
let promise = new Promise((resolve, reject) => {
reject('sss')
})
promise.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
}).finally(() => {
console.log('hello finnally')
})
2.4、Promise.resolve()
new Promise((resolve, reject) => {
resolve("hhhhh")
})
2.5、Promise.reject()
new Promise((resolve, reject) => {
reject('hhhhh')
})
2.6、Promise.all
例子一:
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('111')
}, 1000)
})
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('222')
}, 2000)
})
let promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('333')
}, 3000)
})
Promise.all([promise1, promise2, promise3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
例子二:
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('111')
}, 1000)
})
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("222")
}, 2000)
})
let promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('333')
}, 3000)
})
Promise.all([promise1, promise2, promise3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
2.7、Promise.allSettled
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('111')
}, 1000)
})
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('222')
}, 2000)
})
let promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('333')
}, 3000)
})
Promise.allSettled([promise1, promise2, promise3]).then(res => {
console.log(res)
})
2.8、Promise.race()
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('111')
}, 1000)
})
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('222')
}, 2000)
})
let promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('333')
}, 3000)
})
Promise.race([promise1, promise2, promise3]).then(res => {
console.log(res)
}).catch(err => {
console.log('err' + err)
})
2.9、Promse.any
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('111')
}, 1000)
})
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('222')
}, 2000)
})
let promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('333')
}, 3000)
})
Promise.any([promise1,promise2, promise3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err.errors)
})
三、手写Promise
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_PENDDING = 'pendding'
const PROMISE_STATUS_REJECTED = 'rejected'
function execFunc(func, value, resolve, reject) {
try {
let res = func(value)
resolve(res)
} catch (err) {
reject(err)
}
}
class MyPromise {
constructor(exacutor) {
this.status = PROMISE_STATUS_PENDDING
this.reason = undefined
this.value = undefined
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDDING) {
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDDING) return
this.value = value
this.status = PROMISE_STATUS_FULFILLED
this.onFulfilledFns.forEach(fn => fn(this.value))
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDDING) {
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDDING) return
this.reason = reason
this.status = PROMISE_STATUS_REJECTED
this.onRejectedFns.forEach(fn => fn(this.reason))
})
}
}
exacutor(resolve, reject)
}
then(onFulfilled, onRejected) {
onRejected = onRejected || (err => {
throw err
})
return new MyPromise((resolve, reject) => {
if (this.status === PROMISE_STATUS_FULFILLED) {
if (onFulfilled) execFunc(onFulfilled, this.value, resolve, reject)
}
if (this.status === PROMISE_STATUS_REJECTED) {
if (onRejected) execFunc(onRejected, this.reason, resolve, reject)
}
if (this.status === PROMISE_STATUS_PENDDING) {
if (onFulfilled) this.onFulfilledFns.push(() => {
execFunc(onFulfilled, this.value, resolve, reject)
})
if (onRejected) this.onRejectedFns.push(() => {
execFunc(onRejected, this.reason, resolve, reject)
})
}
})
}
catch (onRejected) {
return this.then(undefined, onRejected)
}
finnally(onFinial) {
this.then(() => {
onFinial()
}, () => {
onFinial()
})
}
static resolve(value) {
return new MyPromise((resolve, reject) => {
resolve(value)
})
}
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
static all(promises) {
return new MyPromise((resolve, reject) => {
let arr = []
promises.forEach(item => {
item.then(res => {
arr.push(res)
if (arr.length === promises.length) {
resolve(arr)
}
}, err => {
reject(err)
})
})
})
}
static allsettle(promises) {
return new MyPromise((resolve, reject) => {
let arr = []
promises.forEach(item => {
item.then(res => {
arr.push({
value: res,
status: PROMISE_STATUS_FULFILLED
})
if(arr.length === promises.length) {
resolve(arr)
}
}, err => {
arr.push({
value: err,
status: PROMISE_STATUS_REJECTED
})
if(arr.length === promises.length) {
resolve(arr)
}
})
})
})
}
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(item => {
item.then(res => {
resolve(res)
}, err => {
reject(err)
})
})
})
}
static any(promises) {
return new MyPromise((resolve, reject) => {
let arr = []
promises.forEach(item => {
item.then(res => {
resolve(res)
}, err => {
arr.push(err)
if(arr.length === promises.length) {
reject(new AggregateError(arr))
}
})
})
})
}
}
|