node.js无法在循环内运行mysql查询

lqfhib0f  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(360)

我在mysql中有两个表,希望根据另一个表的结果查询一个表,所以我编写了一个函数

export function getLocations(req, res) {
const database = new Database();
database.query('select * from districts')
    .then(rows => {
        let appData = [];
        rows.forEach(row => {
            const new_database = new Database();
            new_database.query(`SELECT locations.id,locations.name, IF(subscriptions.id IS NULL,0,1) as subscribed 
            FROM locations 
            LEFT JOIN subscriptions 
            ON (subscriptions.location_id = locations.id AND subscriptions.user_id=1)
            WHERE locations.district=?`,row.id)
            .then(sub_rows => {
                let district=row;
                district["locations"]=sub_rows;
                appData.push(district);
                new_database.close();
            }, err => {
                return new_database.close().then(() => { throw err; })
            })
            .catch(err => {
                console.log(err);
                res.status(500).json("Database Error");
            })

        });
        res.status(200).json(appData);  //final result here
        database.close()
    }, err => {
        return database.close().then(() => { throw err; })
    })
    .catch(err => {
        console.log(err);
        res.status(500).json("Database Error");
    })
}

在这里,我想为第一个查询的每一行运行第二个查询。我得到一个空数组作为结果。我的第一个查询正在正确执行,我记录以查看所有行是否都被返回。有什么问题吗?

mwngjboj

mwngjboj1#

你可以让它工作的异步

rows.forEach(async row => {
        const new_database = new Database();
        await new_database.query(`SELECT locations.id,locations.name, IF(subscriptions.id IS NULL,0,1) as subscribed 
        FROM locations 
        LEFT JOIN subscriptions 
        ON (subscriptions.location_id = locations.id AND subscriptions.user_id=1)
        WHERE locations.district=?`,row.id)
        .then(sub_rows => {
            let district=row;
            district["locations"]=sub_rows;
            appData.push(district);
            new_database.close();
        }, err => {
            return new_database.close().then(() => { throw err; })
        })
        .catch(err => {
            console.log(err);
            res.status(500).json("Database Error");
        })

});

您正在执行的操作是i/o,js是单线程的。这意味着在外行术语中,它不会等待,它将迭代您的循环,在那里它将发出一个请求,在请求处理过程中有一些等待。您需要告诉js这个事件是异步的。为此,您需要使用async/await
指南
foreach异步/等待
异步/等待mdn文档

4si2a6ki

4si2a6ki2#

我没有这台机器的环境。它可能有一些错误,但您可以修复它,如果有,请看下面的逻辑

export function getLocations(req, res) {
const database = new Database();
const promises=[];
database.query('select * from districts')
    .then(rows => {
        let appData = [];
        rows.forEach(row => {
        promises.push(getAnotherQuery(row));
        });
        database.close()
    }, err => {
        return database.close().then(() => { throw err; })
    })
    .catch(err => {
        console.log(err);
        res.status(500).json("Database Error");
    })
    return Promise.all(promises).then(result)=>  res.status(200).json(result);  //final result here

}
getAnotherQuery=(row)=>{
return new Promise((resolve,reject)=>{
const new_database = new Database();
           const appData=[]
            new_database.query(`SELECT locations.id,locations.name, IF(subscriptions.id IS NULL,0,1) as subscribed 
            FROM locations 
            LEFT JOIN subscriptions 
            ON (subscriptions.location_id = locations.id AND subscriptions.user_id=1)
            WHERE locations.district=?`,row.id)
            .then(sub_rows => {
                let district=row;
                district["locations"]=sub_rows;
                appData.push(district);
                new_database.close();
                resolve(appData);
            }, err => {
                return new_database.close().then(() => { throw err; })
            })
            .catch(err => {
                console.log(err);
                res.status(500).json("Database Error");
            })
            });
}

相关问题