使用
Promise
檢查集合本文譯自:How to use async functions with Array.some and every in Javascript -
在第一篇文章中, 我們介紹了async / await 如何幫助執(zhí)行異步命令 ,但是在異步處理集合時卻無濟于事钮孵。在這篇文章中汗菜,當結(jié)果為布爾值時玄窝,我們將研究 some
和 every
函數(shù)用于更有效的 reduce
1. some 和 every 函數(shù)
這些函數(shù)與filter
一樣蚪腋,獲得遞歸函數(shù),但是它們根據(jù)斷言函數(shù)是否返回特定值而返回單個 true / false
。對于some
婚温,如果任何斷言函數(shù)返回 true
,則結(jié)果為true媳否。對于該every
函數(shù)栅螟,如果返回任何false
,則結(jié)果將為false
篱竭。
const arr = [1, 2, 3];
const someRes = arr.some((i) => {
return i % 2 === 0;
});
console.log(someRes);
// true
const everyRes = arr.every((i) => {
return i < 2;
});
console.log(everyRes);
// false
2. 異步 some/every
2.1 使用異步 filter
僅考慮結(jié)果力图,可以使用 async
來模擬這些函數(shù)filter
,在上一篇文章中已經(jīng)介紹了如何將其轉(zhuǎn)換為async
掺逼。
// sync
const some = (arr, predicate) => arr.filter(predicate).length > 0;
const every = (arr, predicate) => arr.filter(predicate).length === arr.length;
// async
const asyncSome =
async (arr, predicate) => (await asyncFilter(arr, predicate)).length > 0;
const asyncEvery =
async (arr, predicate) => (await asyncFilter(arr, predicate)).length === arr.length;
短路(Short-circuiting)
但是吃媒,內(nèi)置的some
/ every
函數(shù)和filter
的實現(xiàn)之間存在重要的區(qū)別。當有一個元素為時返回true時吕喘,some
將短路并且不處理其余元素:
const arr = [1, 2, 3];
const res = arr.some((i) => {
console.log(`Checking ${i}`);
return i % 2 === 0;
});
// Checking 1
// Checking 2
console.log(res);
// true
同樣赘那,every
在第一個錯誤結(jié)果之后停止:
const arr = [1, 2, 3];
const res = arr.every((i) => {
console.log(`Checking ${i}`);
return i < 2;
});
// Checking 1
// Checking 2
console.log(res);
// false
讓我們看看如何編寫一個異步版本,該版本以類似的方式工作并且工作量最少氯质!
2.2 異步 some
最好的解決方案是使用異步進行迭代募舟,并在找到結(jié)果為 true
后立即返回:
const arr = [1, 2, 3];
const asyncSome = async (arr, predicate) => {
for (let e of arr) {
if (await predicate(e)) return true;
}
return false;
};
const res = await asyncSome(arr, async (i) => {
console.log(`Checking ${i}`);
await sleep(10);
return i % 2 === 0;
});
// Checking 1
// Checking 2
console.log(res);
// true
對于第一個元素predicate(e)
返回結(jié)果為 true
,它結(jié)束了for循環(huán)闻察。
2.3 異步 every
類似的結(jié)構(gòu)適用于every
拱礁,這只是對條件求反的問題:
const arr = [1, 2, 3];
const asyncEvery = async (arr, predicate) => {
for (let e of arr) {
if (!await predicate(e)) return false;
}
return true;
};
const res = await asyncEvery(arr, async (i) => {
console.log(`Checking ${i}`);
await sleep(10);
return i < 2;
});
// Checking 1
// Checking 2
console.log(res);
// false
只要predicate(e)
返回false,函數(shù)便會終止而不檢查其他元素蜓陌。
2.4 并行處理
短路( short-circuiting )實現(xiàn)順序地處理元素觅彰,這在資源使用方面很有效吩蔑,但可能導致執(zhí)行時間更長钮热。
例如,如果通過遞歸發(fā)送網(wǎng)絡請求烛芬,則一次發(fā)送一個請求可能會花費一些時間隧期。另一方面飒责,雖然這可能導致發(fā)送更多的請求,但同時發(fā)送所有請求會更快仆潮。
3. 結(jié)論
some
和every
功能很接近異步filter
宏蛉,但要嚴格遵循同步規(guī)范,異步for
循環(huán)是一個更好的選擇性置。
推薦閱讀
如果對你有所幫助拾并,可以點贊、收藏鹏浅。