Napisałem ten kod w lib/helper.js
var myfunction = async function(x,y) {
....
reutrn [variableA, variableB]
}
exports.myfunction = myfunction;
a potem próbowałem użyć go w innym pliku
var helper = require('./helper.js');
var start = function(a,b){
....
const result = await helper.myfunction('test','test');
}
exports.start = start;
Wystąpił błąd
„await działa tylko w funkcji asynchronicznej”
Jaki jest problem?
javascript
node.js
j.doe
źródło
źródło
await
można go używać tylko wewnątrzasync
funkcji. Oznacza to,await
że funkcja jest asynchroniczna, więc musi być zadeklarowana jako taka.Odpowiedzi:
Błąd nie odnosi się do,
myfunction
ale dostart
.Używam okazji tej kwestii doradzić o znanej strukturze z wykorzystaniem anty
await
który jest:return await
.ŹLE
POPRAWNY
Pamiętaj też, że istnieje specjalny przypadek, w którym
return await
jest poprawny i ważny: (używając try / catch)Czy istnieją problemy z wydajnością w przypadku polecenia „return await”?
źródło
start
jakoasync
funkcji (chociaż niektórzy i tak zdecydują się to zrobić, aby być bardziej jednoznacznym)Kiedy pojawił się ten błąd, okazało się, że wywołałem funkcję map w mojej funkcji „async”, więc ten komunikat o błędzie w rzeczywistości odnosi się do funkcji mapy, która nie została oznaczona jako „async”. Omówiłem ten problem, usuwając wywołanie „await” z funkcji mapy i wymyślając inny sposób uzyskania oczekiwanego zachowania.
źródło
someArray.map(async (someVariable) => { return await someFunction(someVariable)})
await
w Twoim kodzie wprowadza w błąd, ponieważArray.map
nie będzie obsługiwał funkcji jako funkcji asynchronicznej. Aby było jasne, po zakończeniumap
funkcjisomeFunction
wszystko będzie w toku. Jeśli naprawdę chcesz poczekać, aż funkcje się zakończą, musisz napisać:await Promise.all(someArray.map(someVariable => someFunction(someVariable)))
lubawait Promise.all(someArray.map(someFunction)))
.Aby użyć
await
, kontekst wykonywania musi miećasync
charakterJak zostało powiedziane, musisz najpierw zdefiniować naturę swojego
executing context
miejsca, w którym jesteś gotów wykonaćawait
zadanie.Wystarczy wstawić
async
przedfn
deklaracją, w której Twojeasync
zadanie zostanie wykonane.Wyjaśnienie:
W swoim pytaniu importujesz to,
method
co maasynchronous
naturę i będzie wykonywane równolegle. Ale miejsce, w którym próbujesz wykonać tęasync
metodę, znajduje się wewnątrz innej,execution context
którą musisz zdefiniować,async
aby użyćawait
.Zastanawiasz się, co się dzieje pod maską
await
zużywa metody / funkcje zwracające obietnicę / przyszłość / zadania iasync
oznacza metodę / funkcję jako zdolną do używania await.Również, jeśli jesteś zaznajomiony
promises
,await
faktycznie robi ten sam proces obietnicy / postanowienia. Tworzenie łańcucha obietnic i wykonywanie następnego zadania wresolve
oddzwonieniu.Więcej informacji można znaleźć w MDN DOCS .
źródło
Bieżąca implementacja
async
/await
obsługuje tylkoawait
słowo kluczowe wewnątrzasync
funkcji Zmieństart
sygnaturę funkcji, aby można było używać jejawait
wewnątrzstart
.Dla zainteresowanych propozycja na najwyższy poziom
await
jest obecnie na etapie 2: https://github.com/tc39/proposal-top-level-awaitźródło
async
- to cały punkt zasync
.--experimental-repl-await
opcji.Miałem ten sam problem i następujący blok kodu podawał ten sam komunikat o błędzie:
Problem polega na tym, że metoda getCommits () była asynchroniczna, ale przekazałem jej argument repo, który również został utworzony przez Promise. Musiałem więc dodać do niego słowo async w ten sposób: async (repo) i zaczęło działać:
źródło
async / await to mechanizm obsługi obietnicy, możemy to zrobić na dwa sposoby
lub możemy użyć await, aby najpierw poczekać na pełne wypełnienie obietnicy, co oznacza, że zostanie odrzucona lub rozwiązana.
Teraz, jeśli chcemy użyć await (oczekiwania na spełnienie obietnicy) wewnątrz funkcji, obowiązkowe jest, aby funkcja kontenera była funkcją asynchroniczną, ponieważ czekamy na asynchroniczne spełnienie obietnicy || ma sens, prawda ?.
źródło
„await działa tylko w funkcji asynchronicznej”
Ale dlaczego? „await” jawnie zamienia wywołanie asynchroniczne w wywołanie synchroniczne, a zatem obiekt wywołujący nie może być asynchroniczny (lub asynchroniczny) - przynajmniej nie dlatego, że wywołanie jest wykonywane w trybie „await”.
źródło
Tak, await / async był świetnym pomysłem, ale implementacja jest całkowicie zepsuta.
Z jakiegoś powodu słowo kluczowe await zostało zaimplementowane w taki sposób, że może być używane tylko w ramach metody asynchronicznej. W rzeczywistości jest to błąd, chociaż nie zobaczysz go jako takiego nigdzie poza tym tutaj. Rozwiązaniem tego błędu byłoby zaimplementowanie słowa kluczowego await w taki sposób, że może być używane tylko DO WYWOŁANIA funkcji asynchronicznej, niezależnie od tego, czy funkcja wywołująca jest sama w sobie synchroniczna, czy asynchroniczna.
Z powodu tego błędu, jeśli używasz await do wywołania prawdziwej funkcji asynchronicznej gdzieś w kodzie, WSZYSTKIE twoje funkcje muszą być oznaczone jako async, a WSZYSTKIE wywołania funkcji muszą używać await.
Zasadniczo oznacza to, że musisz dodać narzut obietnic do wszystkich funkcji w całej aplikacji, z których większość nie jest i nigdy nie będzie asynchroniczna.
Jeśli naprawdę się nad tym zastanowisz, użycie await w funkcji powinno wymagać, aby funkcja zawierająca słowo kluczowe await NIE BYŁA ASYNC - dzieje się tak, ponieważ słowo kluczowe await wstrzyma przetwarzanie w funkcji, w której znajduje się słowo kluczowe await. Jeśli przetwarzanie w tej funkcji jest wstrzymane, to zdecydowanie NIE jest asynchroniczne.
Tak więc, dla twórców javascript i ECMAScript - napraw implementację await / async w następujący sposób ...
źródło
async
, odzwierciedla to fakt, że wiele z nich wymaga wyników procesów zewnętrznych. Moim zdaniem jest to całkowicie kanoniczne.await
możliwości korzystania tylko z wywołań funkcji: w przypadku pojedynczego procesu zewnętrznego tylko jeden punkt w kodzie javascript może zostać powiadomiony o zakończeniu tego procesu. Na przykład, jeśli zawartość pliku jest potrzebna do 3 niezależnych celów, każdy cel musiałby robić niezależnielet content = await readTheFile();
- dzieje się tak, ponieważ nie można czekać na „obietnicę zawartości pliku”, a jedynie „czynność czytania pliku i wznowienie, gdy zostanie czytać".