Następnie wróć z obietnicy ()

119

Mam taki kod javascript:

function justTesting() {
  promise.then(function(output) {
    return output + 1;
  });
}

var test = justTesting();

Zawsze mam niezdefiniowaną wartość testu var. Myślę, że dzieje się tak, ponieważ obietnice nie zostały jeszcze rozwiązane… czy istnieje sposób na zwrócenie wartości z obietnicy?

Priscy
źródło
21
zwracana wartość then()połączenia jest ponownie obietnicą, która opakowuje zwróconą wartość.
Sirko
Masz błąd składniowy, myślę, że to nawet nie analizuje.
djechlin
4
test jest niezdefiniowany, ponieważ justTesting nie zwraca niczego w twoim przykładzie (nie masz żadnego zwrotu). Dodaj zwrot, a test zostanie zdefiniowany jako obietnica.
Jerome WAGNER
1
Dzięki za informację zwrotną… chodzi o to, aby przypisać wyjście +1 do testu.
Priscy
4
Jaka jest zmienna promise. Nie pokazujesz go nigdzie zdefiniowanego i nie zwracasz niczego ze swojej justTesting()funkcji. Jeśli potrzebujesz lepszej pomocy, musisz opisać problem, który próbujesz rozwiązać, zamiast po prostu pokazywać nam kod, który jest tak „wyłączony”, że nawet nie ilustruje tego, co naprawdę próbujesz zrobić. Wyjaśnij problem, który próbujesz rozwiązać.
jfriend00

Odpowiedzi:

136

Kiedy zwracasz coś z połączenia then()zwrotnego, jest to trochę magiczne. Jeśli zwrócisz wartość, następna then()jest wywoływana z tą wartością. Jeśli jednak zwrócisz coś podobnego do obietnicy, następny then()czeka na to i jest wywoływany tylko wtedy, gdy ta obietnica się spełni (powiedzie się / zawiedzie).

Źródło: https://developers.google.com/web/fundamentals/getting-started/primers/promises#queuing-asynchronous-actions

c0ming
źródło
wygląda na to, że z tego powodu mogę obiecać łańcuch dla iteracji tablicy z żądaniami Ajax synchronicznie w stackoverflow.com/q/53651266/2028440
Bằng Rikimaru
84
Nie odpowiedział na pytanie.
Andrew,
Powiązany link
Marinos An
1
Więc jakie jest rozwiązanie?
Apurva
58

Aby użyć obietnicy, musisz albo wywołać funkcję, która tworzy obietnicę, albo musisz utworzyć ją samodzielnie. Tak naprawdę nie opisujesz, jaki problem naprawdę próbujesz rozwiązać, ale oto jak sam stworzyłbyś obietnicę:

function justTesting(input) {
    return new Promise(function(resolve, reject) {
        // some async operation here
        setTimeout(function() {
            // resolve the promise with some value
            resolve(input + 10);
        }, 500);
    });
}

justTesting(29).then(function(val) {
   // you access the value from the promise here
   log(val);
});

// display output in snippet
function log(x) {
    document.write(x);
}

Lub, jeśli masz już funkcję zwracającą obietnicę, możesz użyć tej funkcji i zwrócić jej obietnicę:

// function that returns a promise
function delay(t) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve();
    }, t);
  });
}

function justTesting(input) {
  return delay(100).then(function() {
    return input + 10;
  });
}

justTesting(29).then(function(val) {
  // you access the value from the promise here
  log(val);
});

// display output in snippet
function log(x) {
  document.write(x);
}

jfriend00
źródło
2
co mnie wyrzuca, to podwójne return, czyli justTestingmówi return.then => return. Wiem, że to działa, bo zaimplementowałem to (bcs linting zmusił mnie do odejścia new Promise), ale czy możesz wyjaśnić, jak rozumieć / myśleć o tej parze powrót / powrót?
Ronnie Royston
2
@RonRoyston - Po pierwsze, funkcja, do której przekazujesz, .then()jest funkcją oddzielną od funkcji zawierającej, więc po jej wywołaniu ma swoją własną wartość zwracaną. Po drugie, wartość zwracana przez program .then()obsługi staje się ustaloną wartością obietnicy. Czyli .then(val => {return 2*val;})zmienia rozwiązywaną wartość z valna 2*val.
jfriend00
13

Zrobiłem tutaj to, że zwróciłem obietnicę z funkcji justTesting. Następnie możesz uzyskać wynik, gdy funkcja zostanie rozwiązana.

// new answer

function justTesting() {
  return new Promise((resolve, reject) => {
    if (true) {
      return resolve("testing");
    } else {
      return reject("promise failed");
   }
 });
}

justTesting()
  .then(res => {
     let test = res;
     // do something with the output :)
  })
  .catch(err => {
    console.log(err);
  });

Mam nadzieję że to pomoże!

// old answer

function justTesting() {
  return promise.then(function(output) {
    return output + 1;
  });
}

justTesting().then((res) => {
     var test = res;
    // do something with the output :)
    }
Vidur Singla
źródło
Co by się stało, gdyby w „// zrobić coś z wyjściem” umieściłem instrukcję return? Na przykład: miałbym funkcję „JustTesting (). Then ...” w funkcji nadrzędnej. Czy byłbym w stanie zwrócić wartość w części „to”?
mrzepka
Jeśli chcesz zwrócić wartość z // zrób coś z wynikiem, będziesz musiał dodać zwrot przed justTesing (). Przykład, „return justTesting (). Then ((res) => {return res;});
Vidur Singla
W porządku, tego się spodziewałem, chciałem się tylko upewnić :) Dzięki!
mrzepka
co jeśli zwrócimy test od tego czasu?
MeVimalkumar
3

Wolę używać polecenia „await” i funkcji asynchronicznych, aby pozbyć się niejasności obietnic,

W tym przypadku najpierw napisałbym funkcję asynchroniczną, która zostanie użyta zamiast funkcji anonimowej o nazwie „obietnica.Następnie” część tego pytania:

async function SubFunction(output){

   // Call to database , returns a promise, like an Ajax call etc :

   const response = await axios.get( GetApiHost() + '/api/some_endpoint')

   // Return :
   return response;

}

a potem nazwałbym tę funkcję z funkcji głównej:

async function justTesting() {
   const lv_result = await SubFunction(output);

   return lv_result + 1;
}

Zauważając, że zwróciłem tutaj zarówno funkcję główną, jak i podrzędną do funkcji asynchronicznych.

pszczelarz
źródło
Racja ... Korzystanie z await sprawiło, że było znacznie czystsze, a także rozwiązało problem
karthikeyan