Mysql 数组推送在promise node.js中不起作用

Mysql 数组推送在promise node.js中不起作用,mysql,node.js,Mysql,Node.js,我以前曾尝试将此代码包装在回调中,与该语言提供的任何东西都是异步的。然而,我仍然一事无成 问题是,成员仍然是空的,即使应该用信息推送它。 然而,频道工作正常 奇怪的是 console.log(values); 打印前 console.log(result); 有趣的是 console.log(result) 有正确的数据,但我在哪里 console.log(members) 它是空的 我已经测试过了,查询都是正确的,这实际上是一个推送的问题,并且比当前返回的结果更早得到结果。我假设承诺意

我以前曾尝试将此代码包装在回调中,与该语言提供的任何东西都是异步的。然而,我仍然一事无成

问题是,成员仍然是空的,即使应该用信息推送它。 然而,频道工作正常

奇怪的是

console.log(values);
打印前

console.log(result);
有趣的是

console.log(result)
有正确的数据,但我在哪里

console.log(members)
它是空的

我已经测试过了,查询都是正确的,这实际上是一个推送的问题,并且比当前返回的结果更早得到结果。我假设承诺意味着事情会更加有序,但可能我的理解是错误的

以下是完整的代码:

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));
          });

    });
};

})

恕我直言,您的回调、承诺和异步/等待的组合很难遵循。你最好简化一下。或者,您的名字可能会被以后必须维护此代码的人诅咒

第二个mysql.query方法中的回调在mysql需要时调用,在查询完成或失败时调用。但是您不能在回调代码中解析异步方法的任何承诺或返回。因此,您的console.logresult显示了正确的结果,但您的其他代码无法访问该结果;您的承诺。在调用该方法之前,所有问题都已解决

一般来说,这样做是正确的:

                   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似乎返回了一个承诺。你没有向我们展示这个函数,所以很难猜测如何将它编入你的逻辑

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);
            })
试试这个

从teamspeak\u客户端数据库列表中选择* 迭代serverGroupList时,每个元素上的db查询都是异步的。因此,成员是空的。 此外,foreach需要一个同步函数,所以您必须使用for循环或for of来使用异步等待特性

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);
        });
});

我理解它的所有地方,但我想这是因为我缺乏语言知识。但这行不通,不是吗?我需要用所有foreach结果填充成员,而不仅仅是1。query.serverGroupClientList的定义是什么?它只是查询teamspeak服务器-serverGroupClientListsgid{返回这个。executeservergroupclientlist,{sgid},[-names]。然后是teamspeak.toArray;}我已经尝试了你的新成员推荐代码,“成员仍然是空的。”Pantoflarz做了一些编辑。现在检查,我假设您得到了serverGroupList。我已经运行了您更新的代码,成员仍然为空,但是是的,serverGroupList按预期打印,并带有正确的data@Pantoflarz您使用哪个npm模块进行mysql连接?

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);