一、Promise.resolve()
- 作用
将现有对象转换成 Promise 对象,这个现有对象可以是普通数据(对象),转换为 Promise 对象后状态为 fulfilled,也可以是 Promise 对象,二次转换为 Promise 对象后状态为原本的状态。前者具有一定的应用价值
- 应用 —— 缓存数据
在单页面应用中,组件的频繁切换可能会导致频繁地请求,但短时间内数据并没有变化,所以可以利用 Promise.resolve() 将第一次的请求数据转换成 Promise 对象,实现后续 then 的调用
function ajax(url){
// 取出 挂载在 ajax 函数对象身上的 缓存数据
var cache = ajax.cache || (ajax.cache = {data:null})
// 如果有缓存数据
if(cache.data){
console.log("走缓存")
// 将缓存的数据转换成 Promise 对象
return Promise.resolve(cache.data)
}
// 如果没有缓存数据,返回 Promise 对象
return new Promise((resolve, reject) => {
// 发送 ajax 请求
var xhr = new XMLHttpRequest()
xhr.open('get', url, true)
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
// 成功
resolve(JSON.parse(xhr.responseText))
console.log('不走缓存')
// 缓存数据 —— 挂载在 ajax 函数对象身上
ajax.cache.data = JSON.parse(xhr.responseText)
} else {
// 失败
reject(xhr.responseText)
}
}
}
})
}
// 第一次发请求 —— 不会走缓存
ajax('http://...').then((data) => {...})
// 第二次发请求 —— 会走缓存
setTimeout(() => {
ajax('http://...').then((data) => {...})
}, 1000)
// 第三次发请求 —— 不想走缓存
setTimeout(() => {
// 可先清空缓存
ajax.cache = null;
// 再发请求,不会走缓存
ajax('http://...').then((data) => {...})
}, 2000)
二、Promise.reject()
- 作用
将普通数据(对象)转换成 Promise 对象,状态为 rejected,也可将 Promise 对象二次转换成 Promise 对象,状态为原来的状态
三、Promise.all()
- 作用
将多个 Promise 实例,包装成一个新的 Promise 实例
const p = Promise.all([p1, p2, p3])
// p 的状态由 p1,p2,p3 决定
// 只有 p1,p2,p3 的状态都变成 fulfilled,p 的状态才会变成 fulfilled,此时 p1,p2,p3 的返回值组成一个数据,传递给 p 的回调函数
// 只要 p1,p2,p3 之中有一个被 rejected,p 的状态就变成 rejected,此时第一个被 rejected 的实例的返回值,会传递给 p 的回调函数
- 应用
// 发送多个 ajax 请求
// 请求数据
var list = ['zs', 'li', 'ww']
// 请求函数
function getData(list) {
// 将数组中的普通对象,映射成 Promise 对象
var newlist = list.map(item => ajax(`http://...?name=${item}`))
// 将一个由 Promise 对象组成的数组包装成一个 Promise 对象,并返回
return Promise.all(newlist)
}
// 调用函数,发送请求
getData(list)
.then((res) => {
// 所有 Promise 均没有错误才 fulfilled
})
.catch((err) => {
// 处理 Promise 数组中第一个出现的错误
})
四、Promise.race()
- 作用
将多个 Promise 对象,包装成一个新的 Promise 对象
const p = Promise.race([p1, p2, p3])
// 只要 p1,p2,p3 中有一个对象率先改变状态,p 的状态就跟着改变。那个率先改变的 Promise 对象的返回值,就传递给 p 的回调函数
- 应用 —— 超时检测
// ajax 请求
var p1 = ajax('http://...')
// 定时器 Promise 对象
var p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('超时')
}, 2000)
})
Promise.race([p1, p2]).then(res => {
// 如果 p1 先 fulfilled
console.log(res)
}).catch(err => {
// 如果 p2 先 rejected
console.log(err)
})
五、Promise.allSettled()
- 作用
用来确定一组异步操作是否都结束了(不管成功或失败),包含了 fulfilled 和 rejected 两种情况
- 应用
const promises = [ ajax('/200接口'), ajax('/401接口')]
Promise.allSettled(promises)
.then(res => {
// 过滤出成功的请求
var successRes = res.filter(item => item.status === 'fulfilled')
// 过滤出失败的请求
var errorRes = res.filter(item => item.status === 'rejected')
})
六、Promise.any()
- 作用
只要 Promise 对象有一个变成 fulfilled 状态,包装对象就会变成 fulfilled 状态(如果有多个 fulfilled,则取第一个);如果所有 Promise 对象都变成 rejected 状态,包装对象才会变成 rejected 状态
- 应用
var p1 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('p1 成功')
reject('p1 失败')
}, 1000)
})
var p2 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('p2 成功')
reject('p2 失败')
}, 2000)
})
var p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p3 成功')
}, 3000)
})
Promise.any([p1, p2, p3])
.then(res => {
// 只要有一个成功,就会执行 then
console.log(res)
})
.catch(err => {
// 只有全部都失败,才会执行 catch
console.log(err)
})