在工作中经常会遇到一次请求多个接口依次返回结果的需求场景,例如我在工作中遇到的一个页面中展示多份合同的时候,就需要请求多个不同接口,把所有的合同都依次请求回来,按请求顺序展示出来,供用户阅读和签名。
一、什么是promise
Promise是JavaScript中一种用于处理异步操作的一种方式,例如从服务器获取数据和读取文件,它可以避免回调函数嵌套的问题,使得异步操作更加直观、易于管理和编写。
二、promise三种状态
Pending(进行中): 初始状态,表示异步操作正在进行中,但尚未完成,状态可以转为Fulfilled和Rejected,一旦转变,就不可再变更。
Fulfilled(已完成): 表示异步操作已成功完成。
Rejected(已拒绝): 表示异步操作失败或出错。
Promise的状态反映了异步操作的不同阶段,这些状态使得promise提供了一种更可靠的方式进行异步编程,使得代码易于理解和维护。
三、promise几个主要特点:
状态不可逆转: 一旦 Promise 进入 Fulfilled 或 Rejected 状态,就不可再变为其他状态。
链式调用: 可以通过 .then()
方法来处理异步操作成功的情况,通过 .catch()
方法来处理异步操作失败的情况。这种链式调用的方式使得代码更清晰。
异步执行: Promise 的回调函数(通过 .then()
或 .catch()
注册的函数)总是异步执行,这有助于避免回调地狱(callback hell)。
promise代码示例
const myPromise = new Promise((resolve, reject) => {
// 异步操作,例如请求数据或定时器
const success = true
if (success) {
resolve('操作成功')
} else {
reject('操作失败')
}
})
myPromise
.then((result) => {
console.log(result) // 在异步操作成功时执行
})
.catch((error) => {
console.log(error) // 在异步操作失败时执行
})
.finally(() => {
console.log('end') // 无论 Promise 是成功还是失败,都会执行的回调函数。(用于兜底)
})
四、promise 处理多个请求
第一种:promise.all() 方法
// 第一种
async created() {
let a = this.http("https://api.uomg.com/api/rand.qinghua");
let b = this.http("https://api.uomg.com/api/rand.qinghua");
const [result1, result2] = await Promise.all(
[a, b].map(v => v.catch(e=> console.log(e)))
)
// 输出结果
console.log('result1:', result1)
console.log('result2:', result2)
},
methods:{
async http(url) {
const response = await fetch(url)
return await response.json()
}
}
控制台打印结果
第二种:promise.allSettled() 方法
// 第二种
async created() {
let a = this.http("https://api.uomg.com/api/rand.qinghua")
let b = this.http("https://api.uomg.com/api/rand.qinghua")
let c = this.http("https://api.uomg.com/api/rand.qinghua")
Promise.allSettled([a, b, c]).then(res => {
// 输出结果
console.log('res结果:',res)
}).catch(err => {
console.log(err)
})
},
methods:{
async http(url) {
const response = await fetch(url)
return await response.json()
}
}
控制台打印结果
模拟接口地址错误的情况
async created() {
let a = this.http("https://api.uomg.com/api/rand.qinghua")
let b = this.http("https://api.uomg.com/api/rand.qinghua666") // 接口地址错误
let c = this.http("https://api.uomg.com/api/rand.qinghua")
Promise.allSettled([a, b, c]).then(res => {
// 输出结果
console.log('res结果:',res)
}).catch(err => {
console.log(err)
})
},
methods:{
async http(url) {
const response = await fetch(url)
return await response.json()
}
}
控制台打印结果
说明:虽然接口异常,并不影响后续接口的数据请求 ,多个接口并发请求数据成功
通过 promise.all 和 promise.allSettled 两种方法成功处理了多个请求的场景,当接口异常时通过catch 进行捕获,保证了后续接口的正常执行。