¿Cómo espero a que termine una promesa antes de devolver la variable de una función?

5 minutos de lectura

Todavía estoy luchando con las promesas, pero estoy progresando gracias a la comunidad aquí.

Tengo una función JS simple que consulta una base de datos Parse. Se supone que debe devolver la matriz de resultados, pero obviamente debido a la naturaleza asíncrona de la consulta (de ahí las promesas), la función regresa antes de los resultados, dejándome con una matriz indefinida.

¿Qué debo hacer para que esta función espere el resultado de la promesa?

Aquí está mi código:

function resultsByName(name)
{   
    var Card = Parse.Object.extend("Card");
    var query = new Parse.Query(Card);
    query.equalTo("name", name.toString());

    var resultsArray = [];

    var promise = query.find({
               success: function(results) {
               // results is an array of Parse.Object.
                             console.log(results);
                             //resultsArray = results;
                             return results;
               },

               error: function(error) {
               // error is an instance of Parse.Error.
                             console.log("Error");
               }
    });                           

}

  • También podría considerar usar async/await. El nodo ahora es compatible con async/await listo para usar desde la versión 7.6

    –Viliam Simko

    19/09/2017 a las 21:23

avatar de usuario
Martín Meeser

¿Qué debo hacer para que esta función espere el resultado de la promesa?

Usar async/await (NO forma parte de ECMA6, pero está disponible para Chrome, Edge, Firefox y Safari desde finales de 2017; consulte Puedo usar)

MDN

    async function waitForPromise() {
        // let result = await any Promise, like:
        let result = await Promise.resolve('this is a sample promise');
    }

Agregado debido a un comentario: una función asíncrona siempre devuelve una Promesa, y en TypeScript se vería así:

    async function waitForPromise(): Promise<string> {
        // let result = await any Promise, like:
        let result = await Promise.resolve('this is a sample promise');
    }

  • La función asíncrona aún devolverá un objeto de promesa si se llama sin esperar (o en código no asíncrono). Compruebe el resultado de console.log(waitForPromise()) si no está seguro. Una verificación de console.log (resultado) dentro de la función asíncrona será imprima lo que espera, pero el retorno de la función asíncrona ocurre inmediatamente sin bloqueo y devuelve una promesa. El bloqueo en javascript suele ser muy malo, ya que es una aplicación de un solo subproceso y el bloqueo privará de notificaciones a cualquier otro cliente pub/sub, esencialmente poniendo de rodillas a toda la aplicación.

    – SRM

    15 de junio de 2018 a las 19:59

  • .net tiene .wait() en la “promesa” como clase de tarea. ¿A Javascript le falta esta función? Necesito esperar algo antes de salir de la herramienta de línea de comandos de mi nodo que puede canalizar su salida a otra herramienta. “await” solo funciona dentro de las funciones asíncronas. Lo que significa que no funciona fuera del alcance de una promesa.

    – TamusJRoyce

    31 oct 2018 a las 19:19


  • @SRM Siento que su comentario se basa en una mala interpretación de la muestra: se trata de la Promise.resolve “interna” (como el ejemplo de Promise más simple), por lo que no hay una persona que llama externa como dice en su comentario. Así que decidí actualizar la respuesta.

    – Martín Meeser

    7 de noviembre de 2018 a las 15:42

  • @TamusJRoyce Supongo que es una pregunta en sí misma, pero creo que en C# puede usar Task.ContinueWith(Task), que es la misma idea que ve en la respuesta aceptada (donde se llama “entonces()”).

    – Martín Meeser

    7 de noviembre de 2018 a las 15:52

  • Creo que ahora veo. Prácticamente puedo envolver todo mi script en una gran función asíncrona. Y llame a esa función como la última línea de mi script. Esa función seguiría siendo un poco de placa de caldera. Pero mucho menos de lo que percibí anteriormente. No estoy acostumbrado a escribir funciones dentro de funciones. ¡Gracias @MartinMeeser!

    – TamusJRoyce

    11 de noviembre de 2018 a las 15:23


  • Todo el asunto de las devoluciones de llamada con el success: bit está apagado.

    – Benjamin Grünbaum

    3 de enero de 2015 a las 21:18

  • O mejor: return query.find();.

    – puré

    3 de enero de 2015 a las 21:21

  • También está bien. Lo dejaré así con fines ilustrativos, pero lo agregaré como comentario.

    – html_programador

    3 de enero de 2015 a las 21:22

  • Intenté esto pero los resultados parecen ser indefinidos. resultadosByName(“nombre”).then(función(resultados){ console.log(“arreglo obtenido “+resultados.recuento); });

    – mac_55

    3 de enero de 2015 a las 21:59


  • Gracias, debe haber algún tipo de error dentro de la función de resultados. Está funcionando ahora. Cambié mi console.log a results.length y puedo ver que hay 1 entrada en mi matriz devuelta 🙂

    – mac_55

    03/01/2015 a las 22:30

En realidad no estás usando promesas aquí. Parse le permite usar devoluciones de llamada o promesas; tu elección.

Para usar promesas, haga lo siguiente:

query.find().then(function() {
    console.log("success!");
}, function() {
    console.log("error");
});

Ahora, para ejecutar cosas después de que se complete la promesa, simplemente puede ejecutarla dentro de la devolución de llamada de la promesa dentro del then() llamar. Hasta ahora, esto sería exactamente lo mismo que las devoluciones de llamada regulares.

Para hacer un buen uso de las promesas es cuando las encadenas, así:

query.find().then(function() {
    console.log("success!");

    return new Parse.Query(Obj).get("sOmE_oBjEcT");
}, function() {
    console.log("error");
}).then(function() {
    console.log("success on second callback!");
}, function() {
    console.log("error on second callback");
});

  • ¿Qué tipo de objeto es el objeto de resultados? ya que no parece contener mi matriz

    – mac_55

    3 de enero de 2015 a las 22:01

  • Debe ser una matriz de Parse.Object‘s.

    – puré

    3 de enero de 2015 a las 22:56

  • ¿Qué tipo de objeto es el objeto de resultados? ya que no parece contener mi matriz

    – mac_55

    3 de enero de 2015 a las 22:01

  • Debe ser una matriz de Parse.Object‘s.

    – puré

    3 de enero de 2015 a las 22:56

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad