我以前曾尝试将此代码包装在回调中,以使该语言所提供的内容保持异步。但是,我仍然一无所获。
问题是,即使应随信息一起推送,成员仍为空。 频道,但是效果很好。
很奇怪,
console.log(values);
在
之前打印console.log(result);
有趣的是,
console.log(result)
有正确的数据,但我在哪里
console.log(members)
它是空的。
我已经测试过,查询都是正确的,从字面上看是推送和获取结果的问题早于当前返回的问题(我认为Promises意味着事情会更加有序,但是也许我的理解是错误的)。
这是完整的代码:
module.exports.controller = (query, helper, cache, Database, mysql, config) => {
return async (req, res) => {
let zone = req.body.zone;
let returning = {};
if(!zone){
return res.json(helper.responseJson(false, 'Missing parameter "zone"'));
}
function teleport_available(channel_name){
if(channel_name.indexOf("Nadaj / Usuń") === -1){
return true;
}else{
return false;
}
}
await mysql.query("SELECT * FROM flamespeak_pbot.zones WHERE zone = '"+ zone +"'", async (err, row) => {
if (err) throw err;
row = row[0];
if (row.length == 0) {
return res.json(helper.responseJson(false, "Zone not found."));
} else {
var channelsPromise = new Promise((resolve, reject) => {
const channels = [];
JSON.parse(row.assignGroupAdditional_ch).forEach(additionalCh => {
cache.channelList.filter(channel => channel.cid == additionalCh).forEach(mainCh => {
mainCh.propcache.teleport_available = teleport_available(mainCh.propcache.channel_name);
mainCh.propcache.subchannels = [];
cache.channelList.filter(channel => channel.pid == additionalCh).forEach(subCh => {
subCh.propcache.teleport_available = teleport_available(mainCh.propcache.channel_name);
mainCh.propcache.subchannels.push(subCh);
});
channels.push(mainCh.propcache);
});
});
resolve(channels);
});
var membersPromise = new Promise((resolve, reject) => {
let members = [];
query.serverGroupClientList(row.serverGroupID)
.then(serverGroupList => {
serverGroupList.forEach(member => {
var sql = "SELECT * FROM teamspeak_clientDbList WHERE client_database_id = '" + member.cldbid + "'";
mysql.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
members.push(result);
})
});
})
.then(() => {
console.log(members);
resolve(members);
});
});
}
Promise.all([channelsPromise, membersPromise]).then(function(values) {
console.log(values);
returning = {
'channels' : values[0],
'members' : values[1],
'pbot' : row,
};
res.send(helper.responseJson(true, returning));
});
});
};
};
答案 0 :(得分:0)
相对而言,很难混合使用回调,promise和async / await。您最好简化一下。 (否则可能会被以后必须维护此代码的人诅咒您的名字。)
每当MySQL需要时(无论查询完成还是失败),都会调用第二个mysql.query()
方法中的回调。但是您不会在该回调的代码内解决任何承诺或从异步方法返回。因此,您的console.log(result)
显示正确的结果,但是您的其他代码无法访问该结果;您的Promise.all会在调用该方法之前解析。
通常这样的事情是正确的:
var sql =
"SELECT * FROM teamspeak_clientDbList WHERE client_database_id = '" +
member.cldbid + "'";
mysql.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
members.push(result);
resolve (result); // <<< add this line
})
但是在您的情况下,它可能行不通:您的函数query.serverGroupClientList()
似乎返回了Promise。您没有向我们展示该功能,因此很难猜测如何将其编织到您的逻辑中。
答案 1 :(得分:0)
query.serverGroupClientList(row.serverGroupID)
.then(serverGroupList => {
let members = [];
serverGroupList.forEach(member => {
var sql = "SELECT * FROM teamspeak_clientDbList WHERE client_database_id = '" + member.cldbid + "'";
mysql.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
members.push(result);
})
});
resolve(members);
})
尝试一下
答案 2 :(得分:0)
SELECT * FROM teamspeak_clientDbList
在迭代serverGroupList时,每个元素上的db Query是异步的。因此,成员为空。
此外,foreach需要同步功能,因此您必须使用for-loop或for-of才能使用async-await功能。
var membersPromise = new Promise((resolve, reject) => {
let members = [];
query.serverGroupClientList(row.serverGroupID)
.then(async (serverGroupList) => {
console.log("serverGroupList: ", serverGroupList);
for (let index = 0, arrLen = serverGroupList.length; index < arrLen; index++) {
let member = serverGroupList[index];
var sql = "SELECT * FROM teamspeak_clientDbList WHERE client_database_id = '" + member.cldbid + "'";
await mysql.query(sql, async function (err, result) {
if (err) throw err;
console.log(result);
members.push(result);
});
}
console.log(members);
resolve(members);
});
});
如果您为返回查询的数据库查询编写包装函数,则可以改进嵌套代码。
function fireQuery(mysql, query, params = []) {
return new Promise((resolve, reject) => {
return mysql.query(query, params, (err, data) => {
if (err) return reject(err);
return resolve(data);
});
});
}
// ex -1
let rows = await fireQuery(mysql,query,params);
if(rows.length == 0) {} // your code
// ex-2
let member = await fireQuery(mysql,query2,params2);
members.push(member);