我之前发过一个问题,发现我的问题实际上是异步功能。我设法解决了大部分问题,但我遇到了一个小问题。使用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循环完成?
注意:抱歉,我的部分代码是西班牙语,试图翻译它的重要部分。
答案 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 })
这里调整了代码:
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;
答案 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
变量。