Async / Inside Array#map()
Dostaję błąd czasu kompilacji z tym kodem:
const someFunction = async (myArray) => {
return myArray.map(myValue => {
return {
id: "my_id",
myValue: await service.getByValue(myValue);
}
});
};
Komunikat o błędzie to:
Wait is a reserved word
Dlaczego nie mogę tego tak użyć?
Próbowałem też w inny sposób, ale to daje mi ten sam błąd:
const someFunction = async (myArray) => {
return myArray.map(myValue => {
const myNewValue = await service.getByValue(myValue);
return {
id: "my_id",
myValue: myNewValue
}
});
};
3 answers
Nie możesz tego zrobić tak, jak sobie wyobrażasz, ponieważ nie możesz użyć await
, jeśli nie znajduje się bezpośrednio wewnątrz async
funkcji.
Sensownym rozwiązaniem byłoby przeniesienie funkcji do map
asynchronicznej. Oznacza to, że map
zwróci szereg obietnic. Możemy wtedy użyć Promise.all
, aby uzyskać wynik, gdy wszystkie obietnice powrócą. Ponieważ Promise.all
sama zwraca obietnicę, funkcja zewnętrzna nie musi być async
.
const someFunction = (myArray) => {
const promises = myArray.map(async (myValue) => {
return {
id: "my_id",
myValue: await service.getByValue(myValue)
}
});
return Promise.all(promises);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-01 13:13:04
Jeśli chcesz uruchomić mapę z funkcją mapowania asynchronicznego, możesz użyć następującego kodu:
const resultArray = await Promise.all(inputArray.map(async (i) => someAsyncFunction(i)));
Jak to działa:
-
inputArray.map(async ...)
zwraca tablicę obietnic-po jednej dla każdej wartości winputArray
. - umieszczenie
Promise.all()
wokół tablicy obietnic przekształca ją w jedną obietnicę. - pojedyncza obietnica z
Promise.all()
zwraca tablicę wartości - każda pojedyncza obietnica składa się z jednej wartości. - stawiamy
await
przedPromise.all()
więc że czekamy na połączoną obietnicę, aby rozwiązać i zapisać tablicę rozdzielonych sub-obietnic do zmiennejresultArray
.
Na końcu otrzymujemy jedną wartość wyjściową w resultArray
dla każdego elementu w inputArray
, odwzorowanego za pomocą funkcji someAsyncFunction
. Musimy poczekać, aż wszystkie funkcje asynchroniczne zostaną rozwiązane, zanim wynik będzie dostępny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-08 04:56:48
Dzieje się tak dlatego, że funkcja w map
nie jest asynchroniczna , więc nie możesz oczekiwać w instrukcji return. Kompiluje się z tą modyfikacją:
const someFunction = async (myArray) => {
return myArray.map(async (myValue) => { // <-- note the `async` on this line
return {
id: "my_id",
myValue: await service.getByValue(myValue)
}
});
};
Więc ... nie jest możliwe, aby dać rekomendację bez oglądania reszty aplikacji, ale w zależności od tego, co próbujesz zrobić, albo zrobić funkcję inner asynchroniczną lub spróbować wymyślić jakąś inną architekturę dla tego bloku.
Update: we może się kiedyś uda: https://github.com/MylesBorins/proposal-top-level-await
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-10 10:34:05