Array.fromAsync()
Baseline 2024
Newly available
Since January 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Die statische Methode Array.fromAsync()
erstellt eine neue, flach kopierte Array
-Instanz aus einem asynchronen Iterable, einem Iterable oder einem array-ähnlichen Objekt.
Syntax
Array.fromAsync(arrayLike)
Array.fromAsync(arrayLike, mapFn)
Array.fromAsync(arrayLike, mapFn, thisArg)
Parameter
arrayLike
-
Ein asynchrones Iterable, ein Iterable oder ein array-ähnliches Objekt, das in ein Array konvertiert werden soll.
mapFn
Optional-
Eine Funktion, die auf jedes Element des Arrays angewendet wird. Wenn vorhanden, wird jeder Wert, der dem Array hinzugefügt werden soll, zuerst durch diese Funktion geleitet, und der Rückgabewert von
mapFn
wird stattdessen dem Array hinzugefügt (nachdem er awaited wurde). Die Funktion wird mit den folgenden Argumenten aufgerufen: thisArg
Optional-
Wert, der als
this
beim Ausführen vonmapFn
verwendet wird.
Rückgabewert
Beschreibung
Array.fromAsync()
ermöglicht es Ihnen, Arrays zu erstellen aus:
- asynchronen iterierbaren Objekten (Objekte wie
ReadableStream
undAsyncGenerator
); oder, wenn das Objekt nicht asynchron iterierbar ist, - iterierbaren Objekten (Objekte wie
Map
undSet
); oder, wenn das Objekt nicht iterierbar ist, - array-ähnlichen Objekten (Objekten mit einer
length
-Eigenschaft und indizierten Elementen).
Array.fromAsync()
durchläuft das asynchrone Iterable sehr ähnlich wie for await...of
. Array.fromAsync()
ist im Verhalten fast gleichwertig mit Array.from()
, außer den folgenden Punkten:
Array.fromAsync()
behandelt asynchrone iterierbare Objekte.Array.fromAsync()
gibt einPromise
zurück, das auf die Array-Instanz erfüllt.- Wenn
Array.fromAsync()
mit einem nicht asynchronen iterierbaren Objekt aufgerufen wird, wird jedes Element, das dem Array hinzugefügt werden soll, zuerst awaited. - Wenn ein
mapFn
bereitgestellt wird, werden dessen Eingaben und Ausgaben intern awaited.
Array.fromAsync()
und Promise.all()
können beide ein Iterable von Promises in ein Promise eines Arrays umwandeln. Es gibt jedoch zwei wesentliche Unterschiede:
Array.fromAsync()
wartet auf jeden Wert, der aus dem Objekt nacheinander erzeugt wird.Promise.all()
wartet auf alle Werte gleichzeitig.Array.fromAsync()
durchläuft das Iterable lazy und ruft den nächsten Wert erst ab, wenn der aktuelle abgeschlossen ist.Promise.all()
ruft alle Werte im Voraus ab und wartet auf alle.
Beispiele
Array aus einem asynchronen Iterable
const asyncIterable = (async function* () {
for (let i = 0; i < 5; i++) {
await new Promise((resolve) => setTimeout(resolve, 10 * i));
yield i;
}
})();
Array.fromAsync(asyncIterable).then((array) => console.log(array));
// [0, 1, 2, 3, 4]
Array aus einem synchronen Iterable
Array.fromAsync(
new Map([
[1, 2],
[3, 4],
]),
).then((array) => console.log(array));
// [[1, 2], [3, 4]]
Array aus einem synchronen Iterable, das Promises liefert
Array.fromAsync(
new Set([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]),
).then((array) => console.log(array));
// [1, 2, 3]
Array aus einem array-ähnlichen Objekt von Promises
Array.fromAsync({
length: 3,
0: Promise.resolve(1),
1: Promise.resolve(2),
2: Promise.resolve(3),
}).then((array) => console.log(array));
// [1, 2, 3]
Verwendung von mapFn
Sowohl die Eingabe als auch die Ausgabe von mapFn
werden intern von Array.fromAsync()
awaited.
function delayedValue(v) {
return new Promise((resolve) => setTimeout(() => resolve(v), 100));
}
Array.fromAsync(
[delayedValue(1), delayedValue(2), delayedValue(3)],
(element) => delayedValue(element * 2),
).then((array) => console.log(array));
// [2, 4, 6]
Vergleich mit Promise.all()
Array.fromAsync()
wartet auf jeden Wert, der aus dem Objekt nacheinander erzeugt wird. Promise.all()
wartet auf alle Werte gleichzeitig.
function* makeIterableOfPromises() {
for (let i = 0; i < 5; i++) {
yield new Promise((resolve) => setTimeout(resolve, 100));
}
}
(async () => {
console.time("Array.fromAsync() time");
await Array.fromAsync(makeIterableOfPromises());
console.timeEnd("Array.fromAsync() time");
// Array.fromAsync() time: 503.610ms
console.time("Promise.all() time");
await Promise.all(makeIterableOfPromises());
console.timeEnd("Promise.all() time");
// Promise.all() time: 101.728ms
})();
Keine Fehlerbehandlung für synchrone Iterables
Ähnlich wie bei for await...of
, wenn das Objekt, das durchlaufen wird, ein synchrones Iterable ist und ein Fehler beim Iterieren auftritt, die return()
-Methode des zugrunde liegenden Iterators nicht aufgerufen wird, sodass der Iterator nicht geschlossen wird.
function* generatorWithRejectedPromises() {
try {
yield 0;
yield Promise.reject(3);
} finally {
console.log("called finally");
}
}
(async () => {
try {
await Array.fromAsync(generatorWithRejectedPromises());
} catch (e) {
console.log("caught", e);
}
})();
// caught 3
// No "called finally" message
Wenn Sie den Iterator schließen müssen, müssen Sie stattdessen eine for...of
-Schleife verwenden und jeden Wert selbst await
en.
(async () => {
const arr = [];
try {
for (const val of generatorWithRejectedPromises()) {
arr.push(await val);
}
} catch (e) {
console.log("caught", e);
}
})();
// called finally
// caught 3
Spezifikationen
Specification |
---|
ES Array.fromAsync (2022) # sec-array.fromAsync |
Browser-Kompatibilität
BCD tables only load in the browser