Regresa de una promesa entonces ()

118

Tengo un código javascript como este:

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

var test = justTesting();

Siempre tengo un valor indefinido para la prueba var. Creo que se debe a que las promesas aún no se han resuelto ... ¿hay alguna forma de devolver un valor de una promesa?

Priscy
fuente
21
el valor de retorno de una then()llamada es nuevamente una promesa, que envuelve el valor que devolvió.
Sirko
Tiene un error de sintaxis, no creo que esto siquiera se analice.
djechlin
4
test no está definido porque justTesting no devuelve nada en su ejemplo (no tiene retorno). Agregue una devolución y la prueba se definirá como una promesa.
Jerome WAGNER
1
Gracias por los comentarios ... el punto es asignar la salida +1 para probar.
Priscy
4
Cuál es la variable promise. No lo muestra definido en ninguna parte y no devuelve nada de su justTesting()función. Si desea una mejor ayuda, debe describir el problema que está tratando de resolver en lugar de simplemente mostrarnos un código que está tan "apagado" que ni siquiera ilustra lo que realmente está tratando de hacer. Explique el problema que está tratando de resolver.
jfriend00

Respuestas:

136

Cuando devuelve algo de una then()devolución de llamada, es un poco mágico. Si devuelve un valor, then()se llama al siguiente con ese valor. Sin embargo, si devuelve algo parecido a una promesa, el siguiente lo then()espera y solo se llama cuando esa promesa se establece (tiene éxito / falla).

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

c0ming
fuente
Parece que por esta razón, entonces puedo hacer una cadena de promesa para iterar la matriz con solicitudes Ajax de forma sincrónica en stackoverflow.com/q/53651266/2028440
Bằng Rikimaru
83
No respondió la pregunta.
Andrew
Enlace
Marinos An
1
Entonces, ¿cuál es la solución?
Apurva
58

Para usar una promesa, debe llamar a una función que crea una promesa o debe crear una usted mismo. Realmente no describe qué problema está realmente tratando de resolver, pero así es como crearía una promesa usted mismo:

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

O, si ya tiene una función que devuelve una promesa, puede usar esa función y devolver su promesa:

// 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
fuente
2
lo que me desconcierta es el doble return, es decir, justTestingdice return.then => return. Sé que esto funciona porque lo he implementado (bcs linting me obligó a, lejos de new Promise), pero ¿puedes explicar cómo entender / pensar en ese par de retorno / retorno?
Ronnie Royston
2
@RonRoyston: en primer lugar, la función a la que pasa .then()es una función separada de la función contenedora, por lo que cuando se llama, tiene su propio valor de retorno. En segundo lugar, el valor de retorno de un .then()controlador se convierte en el valor resuelto de la promesa. Entonces, .then(val => {return 2*val;})está cambiando el valor resuelto de vala 2*val.
jfriend00
13

Lo que he hecho aquí es que he devuelto una promesa de la función justTesting. A continuación, puede obtener el resultado cuando se resuelva la función.

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

¡Espero que esto ayude!

// 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
fuente
¿Qué pasaría si en "// hacer algo con la salida" pongo una declaración de retorno? Por ejemplo: tendría el "JustTesting (). Luego ..." dentro de una función principal. ¿Podría devolver un valor dentro de la parte "entonces"?
mrzepka
Si desea devolver un valor de // hacer algo con la salida, tendrá que agregar un retorno antes de justTesing (). Ejemplo, "return justTesting (). Then ((res) => {return res;});
Vidur Singla
Muy bien, eso es lo que esperaba, solo quería asegurarme :) ¡Gracias!
mrzepka
¿y si volvemos a probar desde entonces?
MeVimalkumar
3

Prefiero usar el comando "await" y las funciones asíncronas para deshacerme de las confusiones de las promesas,

En este caso, primero escribiría una función asincrónica, esta se usará en lugar de la función anónima llamada en "promesa. Luego" parte de esta pregunta:

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;

}

y luego llamaría a esta función desde la función principal:

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

   return lv_result + 1;
}

Observando que devolví la función principal y la función secundaria a las funciones asíncronas aquí.

beemaster
fuente
Bien ... Usar await lo hizo mucho más limpio y resolvió el problema
karthikeyan