1.Promise的含义
promise是用于解决异步编程的一种方案,它具有两个特点
1.状态不受外界影响。Promise具有三种状态,pending(进行中),fulfilled(已完成),rejected(已失败),只有resolve()
和reject()
才能改变Promise的状态。
2.一旦改变状态,就不能再次改变。状态只能从pending
变成fulfilled
或者从pending
变成rejected
缺点:
1.不能取消Promise 2.内部抛出的错误不会反应到外部 3.当处于pending状态时,不知道它处于什么阶段
2.基本用法
const promise = new Promise((resolve, reject)=>{
if(/*判断条件*/){
resolve() //改变状态成fulfilled
}else{
reject() //改变状态成rejected
}
})
promise.then(res=>{
// 当promise处于fulfilled时调用
// res为resolve()返回到数据
// 返回一个状态为fulfilled的新的Promise对象
},err=>{
//当promise处于rejected时调用
// err为reject()返回到数据
// 返回一个状态为rejected的新的Promise对象
}).catch(err=>{
// 同promise.then(null, err=>{})或promise.then(undefind,err=>{})一样
}).finally(()=>{
//前面的调用都执行完成之后执行 不管Promise状态如何都会执行
})
3.Promise常有的方法
1.Promise.resolve()
将现有对象转换成一个fulfilled状态的Promise
2.Promise.reject()
将现有对象转换成一个rejected状态的Promise
3.Promise.all()
const p1 = new Promise((resolve, reject)=>{
})
const p2 = new Promise((resolve, reject)=>{
})
const p3 = new Promise((resolve, reject)=>{
})
const promiseArray = [p1, p2, p3]//接收一个Promise数组
const promise = Promise.all(promiseArray)
// 当p1,p2,p3状态都为fulfilled时 promise才会变成fulfilled
// 只要p1,p2,p3中有一个变为rejected状态, promise就会变成rejected
promise
.then(result=>{
console.log(result) // [p1的resolve(), p2的resolve(), p3的resolve()]
})
.catch(err=>{
console.log(err) // 变成rejected状态的 reject()
})
4.Promise.race()
const p1 = new Promise((resolve, reject)=>{
})
const p2 = new Promise((resolve, reject)=>{
})
const p3 = new Promise((resolve, reject)=>{
})
const promiseArray = [p1, p2, p3]//接收一个Promise数组
const promise = Promise.race(promiseArray)
// 只要p1,p2,p3中有一个改变状态, promise就会跟着改变
promise
.then(res=>{
console.log(res) // 为第一个改变状态的Promise返回的resolve()
}).catch(err=>{
console.log(err) // 为第一个改变状态的Promise返回的reject()
})
5.Promise.allSettled()
const p1 = new Promise((resolve, reject)=>{
resolve('p1')
})
const p2 = new Promise((resolve, reject)=>{
reject('p2')
})
const p3 = new Promise((resolve, reject)=>{
resolve('p3')
})
const promiseArray = [p1, p2, p3]//接收一个Promise数组
const promise = Promise.allSettled(promiseArray)
// 只有等p1,p2,p3都改变状态了,不管是fulfilled还是rejected,promise的状态才会改变,且只会变成fulfilled
promise.then(result=>{
console.log(result)
/*结果为
*[{status:'fulfilled', value:'p1'},
*{status:'rejected', reason:'p2'},
*{status:'fulfilled', value:'p3'},
*]
*/
// status只有fullfilled和rejected这两个值
})
6.Promise.any()
const p1 = new Promise((resolve, reject)=>{
resolve('p1')
})
const p2 = new Promise((resolve, reject)=>{
reject('p2')
})
const p3 = new Promise((resolve, reject)=>{
resolve('p3')
})
const promiseArray = [p1, p2, p3]//接收一个Promise数组
const promise = Promise.any(promiseArray)
// 只有等p1,p2,p3都改变状态了,不管是fulfilled还是rejected,promise的状态才会改变,且只会变成fulfilled
promise
.then(result=>{ // 只要有一个状态变成fulfilled promise就会变成fulfilled
console.log(result)
})
.catch(err=>{ // 所有都变成rejected,promise才会变成rejected
console.log(err)
})
3.手写Promise
// promise状态
const PENDING = void 0;
const FULFILLED = 1;
const REJECTED = 2;
class MyPromise {
constructor(executor) {
this.status = PENDING;
this.value = undefined; // 存储resolve的结果
this.reason = undefined; // 存储reject的结果
this.onFulfilledCallbacks = []; // 存储.then的成功回调函数
this.onRejectedCallbacks = [];// 存储.then的失败回调函数
// promise内部的resolve函数 修改状态 存储执行结果调用所有回调函数
const resolve = (value) => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
// 执行上一个Promise的回调函数并修改状态
this.onFulfilledCallbacks.forEach(fn => fn())
}
// promise内部的reject函数 修改状态 存储执行结果调用所有回调函数
const reject = (reason) => {
if (this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
// 执行上一个Promise的回调函数并修改状态
this.onRejectedCallbacks.forEach(fn => fn())
}
executor(resolve, reject)
}
// Promise.resolve函数 返回一个状态为fulfilled的Promise
static resolve (value) {
return new MyPromise(resolve => resolve(value))
}
// Promise.resolve函数 返回一个状态为rejected的Promise
static reject (reason) {
return new MyPromise((resolve, reject) => reject(reason))
}
// .then(res=>{}, err=>{}) 返回一个Promise
then (onFulfillFn, onRejectFn) {
const _this = this
return new MyPromise((resolve, reject) => {
//成功时调用的回调函数
const onFulfilledHandler = (value) => {
try {
// 获取执行结果
const result = onFulfillFn(value)
// 如果回调函数返回的是一个新的Promise 先执行Promise 再往下执行
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
// 修改状态为fulfilled
resolve(result)
}
} catch (err) {
reject(err)
}
}
// 失败时调用的回调函数
const onRejectedHandler = (reason) => {
try {
const result = onRejectFn(reason)
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
//处理错误后,修改状态为fulfilled
resolve(result)
}
} catch (err) {
reject(err)
}
}
if (_this.status === FULFILLED && onFulfillFn) {
onFulfilledHandler(_this.value)
}
if (_this.status === REJECTED && onRejectFn) {
onRejectedHandler(_this.reason)
}
if (_this.status === PENDING) {
// 把回调放到下一个then中执行
this.onFulfilledCallbacks.push(onFulfilledHandler)
this.onRejectedCallbacks.push(onRejectedHandler)
}
})
}
catch (onRejectFn) {
return this.then(() => { }, (reason) => onRejectFn(reason))
}
finally (onFinallyFn) {
return this.then((value) => onFinallyFn(value), (reason) => onFinallyFn(reason))
}
static all (promises) {
return new MyPromise((resolve, reject) => {
const result = []
let c = 0
for (let i = 0; i < promises.length; i++) {
if (promises[i] instanceof MyPromise) {
promises[i].then(res => {
result[i] = res;
c++
}, err => {
reject(err)
})
} else {
result[i] = promises[i];
c++
}
}
if (c === promises.length) {
resolve(result)
} else {
reject(result)
}
})
}
static allSettled (promises) {
return new MyPromise((resolve, reject) => {
const result = []
for (let i = 0; i < promises.length; i++) {
if (promises[i] instanceof MyPromise) {
promises[i].then(res => {
result[i] = { status: 'fulfilled', value: res }
}, err => {
result[i] = { status: 'rejected', reason: err }
})
} else {
result[i] = { status: 'fulfilled', value: promises[i] }
}
}
resolve(result)
})
}
static any (promises) {
return new MyPromise((resolve, reject) => {
const reason = []
let c = 0
for (let i = 0; i < promises.length; i++) {
if (promises[i] instanceof MyPromise) {
promises[i].then(res => {
resolve(res)
}, err => {
reason[i] = err
c++
})
} else {
resolve(promises[i])
}
}
if (c === promises.length) {
reject(reason)
}
})
}
static race (promises) {
return new MyPromise((resolve, reject) => {
const reason = []
let c = 0
for (let i = 0; i < promises.length; i++) {
promises[i].then(res => {
resolve(res)
}, err => {
reject(err)
})
}
})
}
static withResolvers () {
let res
let rej
let promise = new MyPromise((resolve, reject) => {
res = resolve
rej = reject
})
return { promise, resolve: res, reject: rej }
}
}