简体   繁体   English

如何从 Nodejs 中的循环中添加 MySQL 查询结果?

[英]How to add MySQL query results from a loop in Nodejs?

Essentially, I have an object with string keys and values (ex. {"michigan":"minnesota"}).本质上,我有一个带有字符串键和值的 object(例如 {"michigan":"minnesota"})。 I'm trying to loop through all of these key value pairs and make a query from my database, and add the result to a list, which will then be what is returned to the front end.我正在尝试遍历所有这些键值对并从我的数据库中进行查询,并将结果添加到列表中,然后将其返回到前端。

var return_list = []

        Object.keys(obj).forEach(function(key){
            const state1 = key;
            const state2 = obj[key];

            const sql_select = 'SELECT column1,column2 from database WHERE state = ? OR state=?';
        
            db.query(sql_select,[state1,state2], (err,result) => {
                
                return_list.push(result);
            });
        })

This is what I have in simplest terms, and would like to send return_list back to the front end.这就是我最简单的说法,并且想将 return_list 发送回前端。 The problem I'm running into is I can console.log the result within db.query call, but I can't push the result to the list or call it anywhere outside of the query.我遇到的问题是我可以 console.log 在 db.query 调用中记录结果,但我不能将结果推送到列表或在查询之外的任何地方调用它。 I'm fairly new to both front end and back end development, so any possible ideas would definitely be helpful!我对前端和后端开发都很陌生,所以任何可能的想法肯定会有所帮助!

The issue is because the database transaction is not instant, so you need to use either promises or async-await.问题是因为数据库事务不是即时的,所以您需要使用 promises 或 async-await。

Using async await would be something like this (untested),使用异步等待将是这样的(未经测试),

async function get_return_list () {
    var return_list = []

    Object.keys(obj).forEach(function(key){
        const state1 = key;
        const state2 = obj[key];
    
        const sql_select = 'SELECT column1,column2 from database WHERE state = ? OR state=?';
    
         await db.query(sql_select,[state1,state2], (err,result) => {
            
            return_list.push(result);
        });
    })

    return return_list
} 

see for more detail: https://eloquentjavascript.net/11_async.html更多细节见: https://eloquentjavascript.net/11_async.html

First, make sure you are working with mysql2 from npm.首先,确保您使用的是来自 npm 的mysql2 Which provides async method of mysql.其中提供了 mysql 的异步方法。 Second, Note that when you query SELECT , you don't get the "real" result in first.其次,请注意,当您查询SELECT时,您不会首先获得“真实”结果。 Suppose you get result , then, the "real" results are held in result[0] .假设您得到result ,那么“真实”结果将保存在result[0]中。

(async () => {
    const promiseArr = [];

    for (const key of Object.keys(yourOBJ)) {
        const state1 = key;
        const state2 = yourOBJ[key];
        const sql_select = 'SELECT column1,column2 from database WHERE state = ? OR state=?';

        promiseArr.push(db.query(sql_select, [state1, state2]));
    }

    let results;

    try {
        results = await Promise.all(promiseArr);
    } catch (e) {
        throw '...';
    }

    const return_list = results.reduce((finalArray, item) => {
        finalArray = [
            ...finalArray,
            ...item[0],
        ]
    }, []);
})();

The problem is that the forEach returns void.问题是forEach返回 void。
So you can't wait for the asynchronous code to run before you return it.因此,您不能等待异步代码运行后再返回。
When we're dealing with an array of promises such as db queries ( like in your case ) or API calls, we should wait for every one of them to be executed.当我们处理一系列承诺时,例如数据库查询(如您的情况)或 API 调用,我们应该等待它们中的每一个都被执行。
That's when we use the Promise.all那是我们使用Promise.all的时候

Try doing it like this:尝试这样做:

const queryResults = await Promise.all(
   Object.keys(obj).map(async (key) => {
    const state1 = key;
    const state2 = obj[key];

    const sql_select = 'SELECT column1,column2 from database WHERE state = ? OR state=?';

    return new Promise((resolve, reject) => 
      db.query(sql_select,[state1,state2], (err, result) => {
        if (err) 
          return reject(err)
        else
          return resolve(result)
      })
    )
  })
)
console.log('queryResults', queryResults)
// now you give this queryResults back to your FE

Small tips for your fresh start:新开始的小提示:

  • never use var, try always use const or if needed, let.永远不要使用 var,尝试总是使用 const,或者如果需要,让。
  • try always use arrow functions ( () => {...} ) instead of regular functions ( function () {...} ), It's hard to predict which scope this last one is using尝试始终使用箭头函数() => {...} )而不是常规函数( function () {...} ),很难预测最后一个使用的是哪个 scope

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM