Uwaga PRZED USUNIĘCIEM DUPLIKATU: Zdaję sobie sprawę, że podobne pytania zadawano już wiele razy, jednak spędziłem kilka godzin próbując to zaimplementować, korzystając z odpowiedzi innych osób, ostatnio odpowiedź z noseratio w tym wątku Właściwy sposób czekania na zakończenie jednej funkcji przed kontynuowaniem? i bez powodzenia.


Mam serwer nodeJS, który pomyślnie zwraca dane, gdy moja funkcja f1 ich żąda, oraz inną funkcję f2, która wywołuje f1, a następnie ma coś zrobić z danymi wyjściowymi tej funkcji asynchronicznej. Próbuję to zrobić za pomocą składni async / await i dodatkowej obietnicy w f2, jak pokazano poniżej.

async function f1(){
   try{
       let response = await fetch('MY SERVER URL');
       let data = await response.json();
       return await data;
   }
   catch(e) {
       alert(e);
   }
};


function f2() {
    var promise = f1();
    promise.then(function(result) {
        JSONdata = promise.markers;
        console.log("JSON read into f2");
    })    

    console.log(JSONdata);

A potem f2 robi inne rzeczy ...

Problem polega jednak na tym, że doświadczam warunków wyścigu, w wyniku których f1 nie jest zwracany na czas, aby móc cokolwiek z tym zrobić, więc zmienne są niezdefiniowane.

Będziemy wdzięczni za jakąkolwiek pomoc w tym, jak to złagodzić.

0
B_D_E 31 marzec 2020, 22:28

3 odpowiedzi

Najlepsza odpowiedź

Powinieneś albo przenieść logikę, która używa wyniku f1 wewnątrz wywołania zwrotnego then.

function f2() {
    var promise = f1();
    promise.then(function(result) {
        var JSONdata = result.markers;
        console.log("JSON read into f2");

        console.log(JSONdata);
    });
}

Lub zmień f2 na {{X1 }}, więc możesz {{X2 }} zwracana wartość.

async function f2() {
    var result = await f1();
    var JSONdata = result.markers;
    console.log("JSON read into f2");

    console.log(JSONdata);
}

Jeśli jeszcze tego nie zrobiłeś, sprawdź MDN Using Promises przewodnik, który wyjaśnia je dość dokładnie. Gdy zrozumiesz, jak działają obietnice, {{X0 }} / await również stanie się dużo łatwiejsze do zrozumienia.

0
3limin4t0r 31 marzec 2020, 20:07

Trzymaj się tego wzoru.

async func1() { 
  console.log('this is async function')
  return JSON.parse(await fetch(options))
}

func2 () { 
   console.log('this is not async function')
 }

        if(await func1()){
            func2()
        }

A w funkcji 1 masz zbyt wiele oczekiwań. Oczekuj tylko na zwrot obietnicy. I nie powinieneś mylić się na tym poziomie z mieszaniem składni „.then” i „czekaj”. Spróbuj trzymać się jednego wzoru, a następnie zbadaj inny. Następnie wymieszaj.

1
Ivan Kolyhalov 31 marzec 2020, 19:40

Coś takiego powinno działać:

async function f1() {
   try {
       const response = await fetch('MY SERVER URL')
       return await response.json()
   } catch(e) {
       console.error(e)
   }
}

async function f2() {
    const { markers } = await f1()
    console.log(`Result supplied to 'f2': ${markers}`)
}

W Twoim kodzie await w return await data jest zbędne, ponieważ data nie jest obietnicą; również f2 wydaje się niekompletny.

Zwróć uwagę, że chociaż ogólnie return await... jest niepotrzebne w funkcjach async (i uważane za złą formę, nawet jeśli jest nieszkodliwe), jeśli chcesz, aby otaczająca go próba ... złapała odrzucenie obietnicy, to return await... jest konieczne. Zobacz tutaj.

1
Ben Aston 31 marzec 2020, 21:23