1.首先这里需要说明两个函数的用法:
Promise.all()
和 Promise.allSettled()
都是用于处理多个 Promise 的方法,它们有以下区别
---返回结果的不同:
Promise.all()
: 返回一个新的 Promise,当所有 Promise 都成功完成时,该 Promise 才会被解决(resolved),并将所有 Promise 的结果作为一个数组传递给解决处理程序(resolve handler)。如果任何一个 Promise 失败(rejected),那么最终的 Promise 也会失败,并将第一个失败的 Promise 的结果传递给拒绝处理程序(reject handler)。Promise.allSettled()
: 返回一个新的 Promise,当所有 Promise 都已经解决(resolved 或 rejected)时,该 Promise 才会被解决,并且包含一个数组,数组中的每个元素都是一个对象,表示对应的 Promise 结果。这些对象具有status
字段,表示 Promise 的最终状态("fulfilled" 表示成功,"rejected" 表示失败),以及value
或reason
字段,分别表示 Promise 的最终值或拒绝原因。
---处理失败 Promise 的不同:
Promise.all()
: 如果任何一个 Promise 失败,Promise.all()
就会立即将整个操作视为失败,并将失败的 Promise 的结果传递给拒绝处理程序。这意味着当有一个 Promise 失败时,其他已经成功的 Promise 的结果将被忽略。Promise.allSettled()
:Promise.allSettled()
会等待所有的 Promise 都解决(无论成功或失败),然后返回一个包含所有 Promise 结果的数组。即使有 Promise 失败,也不会中断操作。
const promise1 = Promise.resolve('Success 1');
const promise2 = Promise.reject('Error 2');
const promise3 = Promise.resolve('Success 3');
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
// 输出: Error 2
Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
console.log(results);
});
// 输出: [{status: "fulfilled", value: "Success 1"},
// {status: "rejected", reason: "Error 2"},
// {status: "fulfilled", value: "Success 3"}]
2.实际项目终代码如下:
---这个案例解决了在有多个Promise的时候,需要用到这多个Promise里面的数据时,setState的时机问题
---注意保证渲染顺序,需要给数组元素加上索引 tempArr[index] = result.data
//我这有两个状态
const [alldate, setAlldate] = useState<any[]>([]);
const [idkey, setIdkey] = useState(0);
//通过仓位id获取所有的储位
useEffect(() => {
if (positionsid[idkey]?.id != undefined) {
const tempArr: any = [];
const promises: Promise<any>[] = [];
for (let index = 0; index < positionsid[idkey]?.id.length; index++) {
const url = positionsid[idkey]?.id[index];
setState({
spinVisible: true,
});
const promise = getStorageBaseTree({ storageBaseId: url, includeParent: true }).then((result: any) => {
if (result.code === 200) {
tempArr[index] = result.data; // 将结果放入对应的索引位置上,保证了渲染的顺序
}
})
.catch((error) => {
// 处理 error
console.error(error);
});
promises.push(promise);
}
Promise.all(promises)
// Promise.allSettled(promises)
.then(() => {
const mergedArray = Deduplication(Object.values(tempArr.flat().reduce((acc: any, curr: any) => acc.concat(curr), [])))
setAlldate(mergedArray)
setState({
spinVisible: false,
});
});
} else {
setAlldate([])
}
}, [idkey])