Promise
# 概念
从语法上,Promise 是一个构造函数,接收一个函数作为参数,该函数有两个参数 resolve 和 reject。
new Promise(function(resolve, reject) {
})
从功能上,promise 对象用来封装一个异步操作并且可以获取其成功/失败的结果值
# 2 个属性
1) state:表示primose当前的状态,值为 pending(进行中)、fullfilled(完成)、rejected(失败)
2) result:结果
调用 resolve() 可使 pending 变为 fullfilled,调用 reject() 或报错会使 pending 变为 rejected。promise 的状态一旦改变之后就固定了,不会再变
# 方法
1. Promise 构造函数: Promise (excutor) {}
(1) executor 函数: 执行器 (resolve, reject) => {}
(2) resolve 函数: 内部定义成功时我们调用的函数 value => {}
(3) reject 函数: 内部定义失败时我们调用的函数 reason => {}
说明: executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行
let p = new Promise((resolve, reject) => {
})
2. Promise.prototype.then 方法: (onResolved, onRejected) => {}
(1) onResolved 函数: 成功的回调函数 (value) => {}
(2) onRejected 函数: 失败的回调函数 (reason) => {}
说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调
返回值: 一个新的 promise 对象,具体如下:
① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果
let p = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve(111)
}, 1000)
})
p.then(value => console.log('one ->' + value), reason => {})
p.then(value => console.log('two ->' + value))
p.then(value => console.log('three ->' + value))
// 3个都会输出,说明可以为一个 promise 指定多个回调,且当promise 变为对应状态时,相对应的所有回调函数都会执行
3. Promise.prototype.catch 方法: (onRejected) => {}
(1) onRejected 函数: 失败的回调函数 (reason) => {}
说明: then()的语法糖, 相当于: then(undefined, onRejected)
4. Promise.resolve 方法: (value) => {}
(1) value: 成功的数据或 promise 对象
说明: 返回一个成功/失败的 promise 对象
5. Promise.reject 方法: (reason) => {}
(1) reason: 失败的原因
说明: 返回一个失败的 promise 对象
6. Promise.all 方法: (promises) => {}
(1) promises: 包含 n 个 promise 的数组
说明: 返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败
let sign = 0
let p1 = new Promise((resolve, reject) => {
sign ++
resolve(111)
})
let p2 = new Promise((resolve, reject) => {
sign ++
reject(22)
})
let p3 = new Promise((resolve, reject) => {
reject(33)
sign ++
})
let p4 = new Promise((resolve, reject) => {
reject(44)
sign ++
})
let res = Promise.all([p1, p2, p3, p4])
// 返回一个新的 promise,只有当所有 promise 都成功时才成功,此时 result 为一个数组,包含所有 promise 的返回值
// 只要有一个失败的 promise,返回的 promise 的状态就是失败,此时 result 为第一个失败的 promise 的值
console.log(res) // 一个 promise 对象,状态为 rejected,结果为 22
console.log(sign) // 4,表明所有的promise都会执行,而不是遇到失败即返回
7. Promise.race 方法: (promises) => {}
(1) promises: 包含 n 个 promise 的数组
说明: 与 Promise.all()
类似,返回一个新的 promise, 但第一个完成的 promise 的结果状态就是最终的结果状态
# Promise 优缺点
# 优点
指定回调函数的方式更灵活
旧的:必须在启动异步任务前指定
promise:启动异步任务 => 返回promie对象 => 给promise对象绑定回调函 数(甚至可以在异步任务结束后指定/多个)支持链式调用,可以解决回调地狱问题
回调地狱即回调函数嵌套调用,会造成代码不便于阅读、不便于异常处理的问题
# 缺点
- 无法取消 promise,一旦新建就会立即执行,而无法中途取消
- 不指定回调函数就没办法获取到 promise 内部的错误
- 当 promise 处于 pending 状态时,无法得知具体情况,不知道距离完成还差多少
# async / await
- async 函数
async 函数即被 async 修饰的函数,其返回值是一个 Promise 对象,且 Promise 对象的状态由函数执行的返回值确定
async function request(){
}
- await 表达式
- 当 await 的右侧为 Promise 对象时,其值等于 promise 成功的值
let test = async () => {
let res = await new Promise((resolve, reject) => {
resolve(111)
})
console.log(res)
}
test() // 111
- 当 await 的右侧为其他值时,直接将该值作为返回值
async function test(){
let res = await 10
console.log(res)
}
test() // 10
- await 只能用在 async 函数中
- await 修饰的 promise 如果失败了,需要用
try catch
捕捉
async function test(){
try {
let res = await Promise.reject('error')
console.log(res)
} catch (error) {
console.log('error: ', error)
}
}
test() // error: error
- 优缺点
async / await 简化了 promise 的 then 调用链,不需要用回调函数处理。但是因为 await 将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低