JS中Promise.all 和 Promise.allsettled區(qū)別小結(jié)
核心區(qū)別對(duì)比表
| 特性 | Promise.all | Promise.allSettled |
|---|---|---|
| 成功條件 | 所有 Promise 都成功 | 所有 Promise 都完成(無論成功失敗) |
| 失敗條件 | 任何一個(gè) Promise 失敗就立即失敗 | 永遠(yuǎn)不會(huì)失敗 |
| 返回值 | 成功值數(shù)組 | 狀態(tài)對(duì)象數(shù)組 |
| 設(shè)計(jì)目的 | 需要所有結(jié)果都成功才能繼續(xù) | 需要知道每個(gè) Promise 的最終狀態(tài) |
| ES版本 | ES6 (2015) | ES2020 |
| 使用場(chǎng)景 | 并行依賴的操作 | 獨(dú)立的并行操作 |
詳細(xì)對(duì)比
1.行為差異
Promise.all - 全有或全無
const p1 = Promise.resolve('成功1');
const p2 = Promise.reject('錯(cuò)誤2'); // 這個(gè)會(huì)失敗
const p3 = Promise.resolve('成功3');
Promise.all([p1, p2, p3])
.then(results => {
console.log('全部成功:', results);
})
.catch(error => {
console.log('有一個(gè)失敗:', error); // 輸出: "錯(cuò)誤2"
// p1和p3的結(jié)果被丟棄!
});
- 只要有一個(gè)失敗,立即失敗
- 其他 Promise 的結(jié)果會(huì)被丟棄
Promise.allSettled - 全部完成
const p1 = Promise.resolve('成功1');
const p2 = Promise.reject('錯(cuò)誤2');
const p3 = Promise.resolve('成功3');
Promise.allSettled([p1, p2, p3])
.then(results => {
console.log('全部完成:');
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`p${index + 1}: 成功 - ${result.value}`);
} else {
console.log(`p${index + 1}: 失敗 - ${result.reason}`);
}
});
});
// 輸出:
// 全部完成:
// p1: 成功 - 成功1
// p2: 失敗 - 錯(cuò)誤2
// p3: 成功 - 成功3
- 等待所有 Promise 完成
- 返回每個(gè) Promise 的完整狀態(tài)信息
2.返回值結(jié)構(gòu)不同
Promise.all 返回值
// 成功時(shí)返回: [value1, value2, ...]
Promise.all([Promise.resolve(1), Promise.resolve(2)])
.then(values => console.log(values)); // [1, 2]
// 失敗時(shí)返回: 第一個(gè)錯(cuò)誤
Promise.all([Promise.resolve(1), Promise.reject('錯(cuò)誤')])
.catch(error => console.log(error)); // "錯(cuò)誤"
Promise.allSettled 返回值
Promise.allSettled([
Promise.resolve(1),
Promise.reject('錯(cuò)誤'),
Promise.resolve(3)
])
.then(results => {
console.log(results);
/*
[
{ status: 'fulfilled', value: 1 },
{ status: 'rejected', reason: '錯(cuò)誤' },
{ status: 'fulfilled', value: 3 }
]
*/
});
3.實(shí)際應(yīng)用場(chǎng)景
適合 Promise.all 的場(chǎng)景
// 場(chǎng)景1: 需要所有數(shù)據(jù)才能渲染頁面
async function loadDashboard() {
try {
const [user, orders, notifications] = await Promise.all([
fetchUser(),
fetchOrders(),
fetchNotifications()
]);
// 所有數(shù)據(jù)都成功才渲染
renderDashboard({ user, orders, notifications });
} catch (error) {
// 任何一個(gè)失敗就顯示錯(cuò)誤頁面
showErrorPage('加載數(shù)據(jù)失敗');
}
}
// 場(chǎng)景2: 并行執(zhí)行但有依賴關(guān)系
async function processOrder(orderId) {
const [order, inventory, payment] = await Promise.all([
getOrder(orderId),
checkInventory(orderId),
verifyPayment(orderId)
]);
// 三個(gè)檢查都通過才能繼續(xù)
return { order, inventory, payment };
}
適合 Promise.allSettled 的場(chǎng)景
// 場(chǎng)景1: 批量操作,需要知道每個(gè)結(jié)果
async function sendNotifications(users) {
const results = await Promise.allSettled(
users.map(user => sendNotification(user))
);
const successful = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
const failed = results
.filter(r => r.status === 'rejected')
.map(r => r.reason);
console.log(`發(fā)送成功: ${successful.length}, 失敗: ${failed.length}`);
return { successful, failed };
}
// 場(chǎng)景2: 多源數(shù)據(jù)獲取,哪個(gè)快用哪個(gè)
async function getDataFromMultipleSources() {
const results = await Promise.allSettled([
fetchFromPrimaryAPI().catch(() => null), // 主API
fetchFromBackupAPI1().catch(() => null), // 備份API1
fetchFromBackupAPI2().catch(() => null) // 備份API2
]);
// 使用第一個(gè)成功的結(jié)果
for (const result of results) {
if (result.status === 'fulfilled' && result.value) {
return result.value;
}
}
throw new Error('所有數(shù)據(jù)源都失敗了');
}
// 場(chǎng)景3: 清理操作,無論單個(gè)成功失敗都要繼續(xù)
async function cleanupResources(resources) {
const cleanupResults = await Promise.allSettled(
resources.map(resource => resource.cleanup())
);
// 記錄所有清理結(jié)果,但不中斷流程
logCleanupResults(cleanupResults);
}
4.錯(cuò)誤處理差異
// 使用 Promise.all 的錯(cuò)誤處理
Promise.all([task1(), task2(), task3()])
.then(([result1, result2, result3]) => {
// 成功處理
})
.catch(error => {
// 任何一個(gè)失敗都會(huì)到這里
// 但不知道哪些成功了,哪些失敗了
console.error('某個(gè)任務(wù)失敗:', error);
});
// 使用 Promise.allSettled 的錯(cuò)誤處理
Promise.allSettled([task1(), task2(), task3()])
.then(results => {
const errors = results
.filter(r => r.status === 'rejected')
.map(r => r.reason);
const successes = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
if (errors.length > 0) {
console.log(`${errors.length} 個(gè)任務(wù)失敗,但繼續(xù)處理成功的`);
// 可以繼續(xù)處理 successes
}
return { successes, errors };
});
5.互相模擬實(shí)現(xiàn)
// 用 Promise.allSettled 模擬 Promise.all
function promiseAll(promises) {
return Promise.allSettled(promises)
.then(results => {
const rejected = results.find(r => r.status === 'rejected');
if (rejected) {
throw rejected.reason; // 拋出第一個(gè)錯(cuò)誤
}
return results.map(r => r.value); // 返回所有值
});
}
// 用 Promise.all 模擬 Promise.allSettled(不完美)
function promiseAllSettled(promises) {
// 為每個(gè) Promise 添加錯(cuò)誤處理,確保不會(huì)拋出
const wrappedPromises = promises.map(p =>
Promise.resolve(p).then(
value => ({ status: 'fulfilled', value }),
reason => ({ status: 'rejected', reason })
)
);
return Promise.all(wrappedPromises);
}
總結(jié)選擇建議
使用Promise.all當(dāng):
- 所有 Promise 必須都成功才能繼續(xù)
- 操作有強(qiáng)依賴關(guān)系
- 一個(gè)失敗意味著整個(gè)操作失敗
- 需要快速失敗機(jī)制
使用Promise.allSettled當(dāng):
- 需要知道每個(gè) Promise 的最終狀態(tài)
- 操作是獨(dú)立的,一個(gè)失敗不影響其他
- 需要收集所有結(jié)果(成功和失?。?/li>
- 實(shí)現(xiàn)降級(jí)機(jī)制或備用方案
- 執(zhí)行清理或日志記錄操作
簡單記憶:
- Promise.all = "全部成功才算成功"
- Promise.allSettled = "全部完成就是成功"
到此這篇關(guān)于JS中Promise.all 和 Promise.allsettled區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)JS中Promise.all 和 Promise.allsettled內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS實(shí)現(xiàn)搜索關(guān)鍵詞的智能提示功能
最近在百度搜索的時(shí)候,當(dāng)你輸入一個(gè)字或者詞的時(shí)候,他會(huì)給你們彈出一個(gè)下拉框出來,里面是和你相關(guān)的搜索提示,效果非常人性化,基于js怎么實(shí)現(xiàn)搜索關(guān)鍵詞智能提示功能,下面小編通過實(shí)例代碼給大家介紹下,需要的的朋友參考下吧2017-07-07
用javascript關(guān)閉本窗口不彈出詢問框的方法
ie中用close關(guān)閉非open打開的窗口時(shí)回彈出一個(gè)對(duì)話框詢問用戶,怎么去掉這個(gè)框呢,在window.close之前加上window.top.opener = null就可以了2014-09-09
js頁面引導(dǎo)頁的實(shí)現(xiàn)思路總結(jié)
在同學(xué)們使用某些網(wǎng)站的新版本頁面的時(shí)候,經(jīng)常會(huì)出現(xiàn)一個(gè)類似于新手引導(dǎo)一樣的效果,本文主要介紹了js頁面引導(dǎo)頁的實(shí)現(xiàn)思路總結(jié),感興趣的可以了解一下2023-04-04
JavaScript 實(shí)現(xiàn)拖拽效果組件功能(兼容移動(dòng)端)
這篇文章主要介紹了JavaScript 實(shí)現(xiàn)拖拽效果組件功能(兼容移動(dòng)端),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
JS實(shí)現(xiàn)部分HTML固定頁面頂部隨屏滾動(dòng)效果
這篇文章主要介紹了JS實(shí)現(xiàn)部分HTML固定頁面頂部隨屏滾動(dòng)效果,涉及JavaScript響應(yīng)onscroll事件動(dòng)態(tài)操作頁面元素屬性的相關(guān)技巧,需要的朋友可以參考下2015-12-12
用js代碼和插件實(shí)現(xiàn)wordpress雪花飄落效果的四種方法
這篇文章主要介紹了用js代碼和插件實(shí)現(xiàn)wordpress雪花飄落效果的四種方法,需要的朋友可以參考下2014-12-12
js實(shí)現(xiàn)文本框支持加減運(yùn)算的方法
這篇文章主要介紹了js實(shí)現(xiàn)文本框支持加減運(yùn)算的方法,可實(shí)現(xiàn)文本框輸入加減運(yùn)算式同時(shí)右側(cè)實(shí)時(shí)顯示對(duì)應(yīng)計(jì)算結(jié)果的功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08

