Ritorno da una promessa allora ()


119

Ho un codice javascript come questo:

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

var test = justTesting();

Ho sempre un valore indefinito per il test var. Penso che sia perché le promesse non sono ancora state risolte..c'è un modo per restituire un valore da una promessa?


21
il valore di ritorno di una then()chiamata è di nuovo una promessa, che racchiude il valore restituito.
Sirko

Hai un errore di sintassi, non penso nemmeno che venga analizzato.
Djechlin

4
test non è definito perché justTesting non restituisce nulla nel tuo esempio (non hai ritorno). Aggiungi un reso e il test sarà definito come una promessa.
Jerome WAGNER

1
Grazie per il feedback ... il punto è assegnare l'uscita +1 al test.
Priscy

4
Qual è la variabile promise. Non lo mostri definito da nessuna parte e non restituisci nulla dalla tua justTesting()funzione. Se vuoi un aiuto migliore, devi descrivere quale problema stai cercando di risolvere invece di mostrarci semplicemente un codice così "spento" da non illustrare nemmeno cosa stai veramente cercando di fare. Spiega il problema che stai cercando di risolvere.
jfriend00

Risposte:


136

Quando restituisci qualcosa da una then()richiamata, è un po 'magico. Se restituisci un valore, il successivo then()viene chiamato con quel valore. Tuttavia, se restituisci qualcosa di simile a una promessa, il prossimo then()attende su di esso e viene chiamato solo quando quella promessa si risolve (ha successo / fallisce).

Fonte: https://developers.google.com/web/fundamentals/getting-started/primers/promises#queuing-asynchronous-actions


sembra che per questo motivo, quindi posso promettere la catena per l'iterazione di array con richieste Ajax in modo sincrono in stackoverflow.com/q/53651266/2028440
Bằng Rikimaru

84
Non ha risposto alla domanda.
Andrew


1
Allora qual è la soluzione?
Apurva

58

Per usare una promessa, devi chiamare una funzione che crea una promessa o devi crearne una tu stesso. Non descrivi realmente quale problema stai cercando di risolvere, ma ecco come creeresti tu stesso una promessa:

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);
}

Oppure, se hai già una funzione che restituisce una promessa, puoi utilizzare quella funzione e restituire la sua promessa:

// 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);
}


2
quello che mi sconcerta è il doppio return, cioè justTestingdice return.then => return. So che funziona bcs l'ho implementato (bcs linting mi ha costretto a, lontano da new Promise), ma puoi spiegare come capire / pensare a quella coppia ritorno / ritorno?
Ronnie Royston

2
@RonRoyston - Prima di tutto, la funzione a cui passi .then()è una funzione separata dalla funzione contenitore, quindi quando viene chiamata, ha il suo valore di ritorno. In secondo luogo, il valore restituito da un .then()gestore diventa il valore risolto della promessa. Quindi, .then(val => {return 2*val;})sta cambiando il valore risolto da vala 2*val.
jfriend00

13

Quello che ho fatto qui è che ho restituito una promessa dalla funzione justTesting. È quindi possibile ottenere il risultato quando la funzione viene risolta.

// 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);
  });

Spero che questo ti aiuti!

// old answer

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

justTesting().then((res) => {
     var test = res;
    // do something with the output :)
    }

Cosa succederebbe se in "// fai qualcosa con l'output" inserissi un'istruzione return? Ad esempio: avrei "JustTesting (). Then ..." all'interno di una funzione padre. Potrei restituire un valore all'interno della parte "allora"?
mrzepka

Se vuoi restituire un valore da // fare qualcosa con l'output, dovrai aggiungere un ritorno prima di justTesing (). Esempio, "return justTesting (). Then ((res) => {return res;});
Vidur Singla

Va bene, è quello che mi aspettavo, volevo solo essere sicuro :) Grazie!
mrzepka

cosa succede se restituiamo il test da allora?
MeVimalkumar

3

Preferisco usare il comando "await" e le funzioni asincrone per eliminare le confusioni di promesse,

In questo caso, scriverei prima una funzione asincrona, questa verrà utilizzata al posto della funzione anonima chiamata sotto "promise.then" parte di questa domanda:

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;

}

e quindi chiamerei questa funzione dalla funzione principale:

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

   return lv_result + 1;
}

Notando che ho restituito sia la funzione principale che la funzione secondaria alle funzioni asincrone qui.


Giusto ... L'uso di await lo ha reso molto più pulito e ha risolto il problema
karthikeyan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.