1、什么是Promise
- Promise 是一个类
- 当通过 new Promise() 创建时,需传入一个执行函数 ,我们称之为 executer
- executer 在 Promise 创建时会立即执行,并传入两个回调函数作为参数:executer(resolve, reject)
- 当调用 resolve 回调函数时,会执行 Promise 对象的 then 方法传入的回调
- 当调用 reject 回调函数时,会执行 Promise 对象的 catch 方法传入的回调
- Promise 是一个状态机,分为 3种状态 :
- pending :待定状态,执行 executer 后,处于该状态。(初始状态)
- fuifilled :兑现状态,调用 resolve 后,Promise 状态变更为 fulfilled,且无法再次更改。
- rejected :拒绝状态,调用 reject 后,Promise 状态变更为 rejected,且无法再次更改。
javascript
// 模拟网络请求
function request(cb) {
let flag = !!(Math.random() <= 0.5)
return new Promise((resolve, reject) => {
setTimeout(() => {
if (flag) {
resolve("成功消息")
return;
}
reject("失败消息")
}, 1000)
})
}
console.log("请求开始")
request().then(
msg => {
console.log("成功",msg)
},
err => {
console.log("失败",err)
}
)
2、resolve 的参数
- 如果传入的是普通的值或者推向,则会传递到 then 方法的参数中
- 如果传入的是一个 Promise ,则当前 Promise 状态会由传入的Promise决定
javascript
const prom = new Promise((resolve, reject) => {
resolve('success')
})
new Promise((resolve, reject) => {
resolve(prom)
}).then(data => {
console.log("data", data)
}).catch(err => {
console.err("err", err)
})
// 输出 data success
- 如果传入的是一个 thenable对象 ,会执行对象的 then 方法,由该 then 方法决定后续状态
javascript
new Promise((resolve, reject) => {
resolve({
then(resolve,reject) {
reject("error)
}
})
}).then(data => {
console.log("res", res)
}).catch(err => {
console.log("err", err)
})
// 输出 err error
3、Promise 的实例方法
then 方法
-
概念
- 通过 then 方法可以对 Promise 中的 resolve 进行处理,then 方法的返回值是一个新的 Promise 实例
-
多次调用 then 方法
-
同一个 Promise 实例可以同时调用多个 then 方法,当 Promise 中的 resolve 被调用时,所有的 then 方法传入的回调函数都会被调用
javascriptconst prom = new. Promise(resolve => { resolve("你好") }) prom.then(msg => console.log(msg)) prom.then(msg => console.log(msg)) prom.then(msg => console.log(msg)) /* 输出 你好 你好 你好 */
-
-
then 方法传入的回调函数可以有返回值
-
如果返回的是普通值 ,那么这个普通值作为一个新的 Promise 的 resolve 值
javascriptconst prom = new Promise(resolve => { resolve("你好"); }) prom.then(() => 'then').then(res => console.log(res)) // prom.then(() => 'then')等价于 prom.then(() => { return new Promise(resolve => { resolve('then') }) }) // 输出 then -
如果返回的是 Promise ,那么就可以再次调用此 Promise 的 then 方法
-
如果返回的是一个 thenable 对象 ,则 resolve 会传递给下一个 Promise
javascriptconst promise = new Promise(resolve => { resolve('你好') }) promise.then(() => { return { then(resolve) { return resolve('success') } } }).then(msg => console.log(msg)) // 输出 success
-
catch 方法
除了 then 方法的第二个参数来捕获 reject 错误外,我们还可以通过 catch 方法来捕获,catch 返回的也是一个新的 Promise。
javascript
const promise = new Promise((resolve, reject) => {
reject('error')
})
promise.then(undefined, err => {
// 打印err
console.log(err)
})
// 这种写法不太符合'promise/a+规范'
promise.catch(err => {
// 打印err
console.log(err)
})
// 符合规范的写法
promise.then(() => {}).catch(err => {console.log(err)})
*注意* catch 本质上是对 Promise 的 then 方法的封装,所以同样也是可以多次调用 的,只要保证 Promise 实例的状态是 rejected ,那么就会调用 catch 方法
finally 方法
Promise 实例 状态无论是变更为 fulfilled 还是 rejected,finally 方法都会执行,finally 方法不接受任何的参数
javascript
const promise = new Promise((resolve, reject) => {
reject('error')
})
promise.then(() => {}).catch(err => {console.log(err)}).finally(() => {
console.log('finally code execute')
})
4、Promise 的类方法
resolve 方法
- 参数
- 参数本身是 Promise
- 参数是 原始值/普通对象
- 参数是一个 thenable对象
javascript
const foo = {
name: "alex"
}
function bar(obj) {
return new Promise(resolve => {
resolve(obj)
})
}
bar(foo).then(res => {
console.log(res)
})
// 其中的 function bar 等价于
function bar1(obj) {
return Promise.resolve(obj)
}
reject 方法
Promise.reject() 方法和 Promise.resolve() 方法 用法类似,主要区别是,reject方法用于处理Promise 拒绝逻辑
all 方法
Promise.all(proms) ,参数接收一个 Promise 队列,返回的是一个 Promise 实例,当 proms 总的所有 Promise 执行完成 且 状态均为 fulfilled 时,结果实例的状态才会变为 fulfilled,反之,结果实例的状态为 rejected。
当 Promise.all(proms) 的状态为 fulfilled 时,then(res) 的参数 res 就是 proms 对应实例成功后的值所形成的数组。
javascript
let i = 0;
function genPromise() {
return Promise.resolve(`success${i = i + 1}`)
}
const proms = [
genPromise(),
genPromise(),
genPromise(),
];
Promise.all(proms).then(res => {
console.log('res' , res)
})
// 输出 ['success1', 'success2', 'success3']
当 Promise.all(proms) 的参数 proms 中存在 rejected 时,结果实例状态也会更改为 rejoiced,同时返回停止运行剩余 Promise ,结果返回 状态为 rejected 的 Promise 的值。
javascript
let i = 0;
function genPromise() {
return new Promise(resolve => {
resolve(`success${(i = i + 1)}`)
})
}
const promiseArr = [
genPromise(),
new Promise((resolve, reject) => {
reject('error1')
}),
new Promise((resolve, reject) => {
reject('error2')
})
]
Promise.all(promiseArr).then(res => {
console.log('res', res)
}).catch(err => {
console.log(err)
})
// 输出 'error1'
allSettled 方法
- 参数接收一个 Promise 队列,返回 一个Promise 实例
- 返回 Promise 实例,会在所有 Promise 实例执行完毕后,状态方可变更为 fulfilled,且结果实例状态只能由 pending ------> fulfilled.
- 无论队列中的 Promise 实例的状态如何,都能获取到结果
javascript
const promiseArr = [
new Promise((resolve, reject) => {
resolve('success1')
}),
new Promise((resolve, reject) => {
reject('error')
}),
new Promise((resolve, reject) => {
resolve('success2')
}),
]
Promise.allSettled(promiseArr).then(res => {
console.log('res', res)
})
/* 结果:
res [
{ status: 'fulfilled', value: 'success1' },
{ status: 'rejected', reason: 'error' },
{ status: 'fulfilled', value: 'success2' }
]
*/
race 方法
- 参数接收一个 Promise 队列,返回一个 Promise 实例
- 对 Promise 队列的完成情况进行监控,当某个任务最前完成(无论是fulfilled/rejected),那么返回的结果实例状态也会对应的变更,同时捕获最先完成的 Promise 的结果
javascript
const promiseArr = [
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success1')
}, 1000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
reject('error')
}, 2000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success2')
}, 3000)
}),
]
Promise.race(promiseArr).then(res => {
console.log('res', res)
}).catch(err => {
console.log('err', err)
})
// 结果 res success1
any 方法
- 参数接收一个 Promise 队列,返回一个 Promise 结果实例
- 当某个 Promise 状态变更为 fulfilled 或 所有的 Promise 状态均为 rejected 时,结果实例的状态才能确定并返回
javascript
const promiseArr = [
new Promise((resolve, reject) => {
setTimeout(() => {
reject('error')
}, 2200)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
reject('error')
}, 2000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
reject('error')
}, 3000)
}),
]
Promise.any(promiseArr).then(res => {
console.log('res', res)
}).catch(err => {
console.log('err', err)
})
// 遇到第一个fullfilled,那么转变返回的Promise实例的状态
// 如果所有的都是rejected, 那么只有所有执行完毕后,返回的Promise实例才会转变
// 并且会抛出错误