回调直到for循环查询完成

时间:2016-06-08 19:26:09

标签: javascript mysql asynchronous

我之前发过一个问题,发现我的问题实际上是异步功能。我设法解决了大部分问题,但我遇到了一个小问题。使用async我使用瀑布为一些查询创建订单...

exports.getMenu = function(id_restaurant, callback){
    async.waterfall([
        async.apply(firstQuery, id_restaurant),
        secondQuery,
        thirdQuery,
        fourthQuery,
        formMenu
    ], function(err, result){
        if(err){
            console.log(err);
        }

        callback(result);
    });
};

一切都有效,直到fourthQuery,我必须循环才能获得所有菜单。

function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback){
    var size = array_nombresSecc.length;
    var array_secciones = array_secciones;
    var array_nombresSecc = array_nombresSecc;

    var dishes = [];

    pool.getConnection(function(err, connection) {

        if(err) { 
            console.log(err); 
            callback(true); 
            return; 
        }
        for (var i = 0; i < size; i++) {
            connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [array_secciones[i]], 
                function(err, results2) {
                    if(err) { 
                        console.log(err); 
                        callback(true); 
                        return; 
                    }

                    console.log("Result query 4 " + JSON.stringify(results2));
                    dishes[i] = results2; 
                    console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[i])); 
                    // this prints the result but only if it has a value over 2
            });
        }; 
    }); // pool

    console.log("I'm sending " + dishes); // this logs an empty array

    callback(null, dishes, array_nombresSecc);
};

所以我可以看到,通过打印每个循环的'i'值,它总是具有值2.因为那是'size'值。此外,即使它保存了索引'2'的结果,我相信甚至在for循环完成之前就已经完成了回调,因为我的第五个函数正在接收一个空数组。

如何让我的代码等待回调,直到我的for循环完成?

注意:抱歉,我的部分代码是西班牙语,试图翻译它的重要部分。

2 个答案:

答案 0 :(得分:1)

有几种方法可以解决这个问题,一种是研究promise架构。 Promise.all将允许您提供一个回调来处理每个子承诺的值。

要使用您已经拥有的内容,我会将值推送到您的数据库阵列中,而不是将它们专门分配给i索引,然后检查该数组的大小每个连接的结束。当数组长度与大小匹配时,触发回调。 (见下文)

如果您需要一种方法将每个结果与特定的i值绑定,我建议将它们作为对象推送

dishes.push({'index': i, 'dish': results2})

之后,如果您需要只有菜肴的数组,您可以按该索引值对数组进行排序并运行地图功能。

dishes.sort(function(a,b){ return a.index - b.index; })
dishes = dishes.map(function(a){ return a.dish })

这里调整了代码:

&#13;
&#13;
function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback) {
  var size = array_nombresSecc.length;
  var array_secciones = array_secciones;
  var array_nombresSecc = array_nombresSecc;

  var dishes = [];

  pool.getConnection(function(err, connection) {

    if (err) {
      console.log(err);
      callback(true);
      return;
    }
    for (var i = 0; i < size; i++) {
      connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [array_secciones[i]],
        function(err, results2) {
          if (err) {
            console.log(err);
            callback(true);
            return;
          }

          console.log("Result query 4 " + JSON.stringify(results2));
        
        
          dishes.push(results2)
          
          if(dishes.length == size){
            console.log("I'm sending " + dishes);
            callback(null, dishes, array_nombresSecc)
          }
        
        
          console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[i]));
          // this prints the result but only if it has a value over 2
        });
    };
  }); // pool

  ;
};
&#13;
&#13;
&#13;

答案 1 :(得分:0)

由于您已经在使用异步,我建议您使用async.each()替换for()中的fourthQuery循环。

更新的fourthQuery将如下所示:

function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback){
    var size = array_nombresSecc.length;
    var array_secciones = array_secciones;
    var array_nombresSecc = array_nombresSecc;

    var dishes = [];

    pool.getConnection(function(err, connection) {
        if(err) { 
            console.log(err); 
            callback(true); 
            return; 
        }
        async.each(array_secciones,
            function(item, itemCallback) {
                // Function fun for each item in array_secciones
                connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [item], 
                    function(err, results2) {
                        if(err) { 
                            console.log(err); 
                            return itemCallback(true);
                        }

                        console.log("Result query 4 " + JSON.stringify(results2));
                        dishes.push(results2);
                        console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[dishes.length-1])); 
                        // this prints the result but only if it has a value over 2
                        return itemCallback();
                    });
            },
            function(err) {
                // Function run after all items in array are processed or an error occurs
                console.log("I'm sending " + dishes); // this logs an empty array
                callback(null, dishes, array_nombresSecc);
            });
    }); // pool
};

或者,您可以使用async.map(),它处理在最终回调中收集结果,因此不依赖于dishes变量。