1. 程式人生 > 程式設計 >Array.filter中如何正確使用Async

Array.filter中如何正確使用Async

1. 如何僅保留滿足非同步條件的元素

在第一篇文章中,我們介紹了 async / await 如何幫助處理非同步事件,但在非同步處理集合時卻無濟於事。在本文中,我們將研究該filter函式,它可能是支援非同步函式的最直觀的方法。

2. Array.filter

該filter函式僅保留通過條件的元素。它得到一個斷言( predicate )函式,並且此函式返回 true / false 值。結果集合僅包含斷言( predicate )返回 true 的元素。

const arr = [1,2,3,4,5];

const syncRes = arr.filter((i) => {
	return i % 2 === 0;
});
console.log(syncRes);
// 2,4

3. filter 結合 map 使用

這次的非同步版本要複雜一些,它分為兩個階段。第一個通過斷言函式非同步地對映陣列,從而生成true / false 值。然後第二步是利用第一步的結果同步 filter

Array.filter中如何正確使用Async

const arr = [1,5];

const asyncFilter = async (arr,predicate) => {
	const results = await Promise.all(arr.map(predicate));

	return arr.filter((_v,index) => results[index]);
}

const asyncRes = await asyncFilter(arr,async (i) => {
	await sleep(10);
	return i % 2 === 0;
});

console.log(asyncRes);
// 2,4

或單行實現:

const asyncFilter = async (arr,predicate) => Promise.all(arr.map(predicate))
.then((results) => arr.filter((_v,index) => results[index]));

Array.filter中如何正確使用Async

併發

上面的實現同時執行所有斷言函式。通常,這很好,但是與所有其他功能一樣,它可能會使某些資源變得過分緊張。幸運的是,由於上述實現依賴於此map,因此可以使用相同的併發控制元件。

4. filter 結合 reduce 使用

除了使用非同步map與同步之外filter,非同步reduce 也可以完成這項工作。由於它只是一個功能,因此即使沒有提供相同級別的控制,結構也更加容易。

首先,從一個空陣列([])開始。然後通過斷言函式執行下一個元素,如果通過則將其追加到陣列。如果沒有,請跳過它。

Array.filter中如何正確使用Async

// concurrently
const asyncFilter = async (arr,predicate) => 
	arr.reduce(async (memo,e) =>
		await predicate(e) ? [...await memo,e] : memo,[]);

Array.filter中如何正確使用Async

請注意,await predicate(e) 在 await memo 之前,這意味著這些將並行呼叫。

順序處理

要在呼叫下一個謂詞函式之前等待其結束,請更改await 的順序:

// sequentially
const asyncFilter = async (arr,e) => 
		[...await memo,...await predicate(e) ? [e] : []],[]);

此實現等待上一個元素,然後根據斷言(...[e]或...[])的結果有條件地附加一個元素。

Array.filter中如何正確使用Async

5. 結論

雖然非同步filter是可能的,但它最初的工作方式看起來很奇怪。儘管併發控制仍然可用,但與其他非同步功能相比,它們需要更多的計劃去控制它。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。