Mi objetivo es crear un objeto JSON, a partir de un párrafo de texto, que luego pueda insertar como documento en MongoDB. Estoy usando nodejs y quería ir por el enfoque asíncrono.

Mi JSON tiene parámetros así

{
   height:height,
   weight:weight
}

Mi lógica es esta

Cree un módulo con funciones asíncronas que analice el texto y extraiga el peso y la altura utilizando expresiones regulares.

Pero entonces, ¿cómo combinaría todas las respuestas de estas funciones en un JSON que puedo importar a la vez?

Estoy pensando en algo como esto

var get_height = require().height;
var get_weight = require().weight;

exports.contr = function(){
   var height,
       weight;
   get_height(text, function(err, res){
      if(err)
          throw(err)
      height=res;
   });

   get_weight(text, function(err, res){
      if(err)
          throw(err)
      weight=res;
   });
   //All other async functions
   combine_json(height, weight, ... , function(err, res){
       if(err)
          throw(err);

       console.log(res); //the json was successfully inserted into mongoDB
   }); 
}

Encuentro asíncrono confuso y en el ejemplo anterior no estoy seguro de dos cosas

  1. combine_json no se ejecutaría sin esperar los datos de las dos funciones anteriores (peso, altura)

  2. ¿Cuál es la mejor práctica para manejar estos casos? ¿Debo usar las funciones de sincronización y esperar de arriba a abajo para que cada una haga lo suyo y luego ejecutar la última o puedo aprovechar asincrónica?

0
Ando 12 may. 2016 a las 03:46

3 respuestas

La mejor respuesta

La forma más simple de esperar los resultados de dos funciones asincrónicas independientes es usar promesas y Promise.all. Para esto, asumiremos que get_height y get_weight devuelven un Promise y pueden usarse como tales:

get_height().then(function (height) { console.log(height); });

Entonces es trivial combinar dos de esas promesas:

Promise.all([get_height(), get_weight()]).then(function (results) {
    combine_json(results[0], results[1]);
});

Consulte https://developer.mozilla.org/en- US / docs / Web / JavaScript / Reference / Global_Objects / Promise para obtener documentación y detalles.

1
deceze 12 may. 2016 a las 01:01

Si no sabe nada de Promesas, primero debe saber cómo funcionan las devoluciones de llamada. Si no desea una solución elegante con Promise.all() y solo quiere que su código funcione, necesita funciones anidadas. Cuando esté dentro de la devolución de llamada get_height, debe llamar a get_weight y lo mismo cuando esté dentro de la devolución de llamada get_weight, debe llamar a combine_json(). El único problema es que debe esperar a que get_height llame a get_weight. Esto se resuelve con Promise.all () como se dice.

   get_height(text, function(err, height){
      if(err)
          throw(err);
      get_weight(text, function(err, weight){
         if(err)
            throw(err);
         //All other async functions
         combine_json(height, weight, ... , function(err, res){
             if(err)
                throw(err);
             console.log(res); //the json was successfully inserted into mongoDB
         }); 
      });
   });
0
Jose Hermosilla Rodrigo 12 may. 2016 a las 01:13

Las promesas son su mejor opción, pero si no quiere usarlas por alguna razón y prefiere el estilo de devolución de llamada, entonces

function get_height_and_weight(text, callback) {
  var have_height = false;
  var have_weight = false;
  var result = {};

  get_height(text, function(err, height) {
    if (err) callback(err);
    have_height = true;
    result.height = height;
    if (have_weight) callback(null, result);
  });

  get_weight(text, function(err, weight) {
    if (err) callback(err);
    have_weight = true;
    result.weight = weight;
    if (have_height) callback(null, result);
  });
}

Este es un caso especial del caso de llamadas asíncronas paralelas que async.parallel podría manejar mejor.

0
user663031user663031 12 may. 2016 a las 02:34