NodeJs从数据库查询返回的数组是未定义的。

huangapple go评论77阅读模式
英文:

NodeJs returned array from database query is undefined

问题

The issue you're facing seems to be related to asynchronous behavior in your Node.js application. The problem lies in the fact that getSubData function is asynchronous and does not wait for the database query to finish before returning the result. As a result, arows is undefined when you try to access its length property in the getData function.

To fix this, you need to handle the asynchronous nature of the database queries. One way to do this is by using Promises or async/await. Here's an example using async/await:

module.exports = {

   getData: async () => {
      let dbc = require('./mods/db.js');
      try {
         let rows = await module.exports.getSubData();
         console.log('arows.length:', rows.length);
      } catch (err) {
         console.log('Error 1:', err);
      }
   },

   getSubData: () => {
      return new Promise((resolve, reject) => {
         let dbc = require('./mods/db.js');
         dbc.query(`
            SELECT 10 rn, 'Ten' rt UNION
            SELECT 20 rn, 'Twenty' rt UNION
            SELECT 30 rn, 'Thirty' rt ;
         `,
         function (err, rows) {
            if (err) {
               reject(err);
            } else {
               console.log('arows:', rows.length);
               resolve(rows);
            }
         });
      });
   }
}

In this modified code, the getSubData function returns a Promise that resolves with the database query result. The getData function is now declared as async and uses await to wait for the getSubData function to complete before proceeding.

This should solve the issue you're experiencing with the undefined value of arows.

英文:

An NodeJs app we are wrting has a problem with the query data returned as an array being undefined. I cannot find an exact match for our issue.

The following test case reproduces the problem. It is something to do with the calling function not waiting for the called function to finish? I'm not a JavaScript expert, and this behaviour does not make sense to me.

themod.js

module.exports = {

   getData: () => {
      let dbc = require('./mods/db.js');
      dbc.query(`

         SELECT 1 rn, 'One' rt UNION
         SELECT 2 rn, 'Two' rt UNION
         SELECT 3 rn, 'Three' rt ;

         `,
         function (err, rows) {
            if (err) {
              console.log ( ' Error 1: ' , err );
            } else {
               arows =  module.exports.getSubData();
               console.log ( 'arows.length: ', arows.length );
            }
          })
   },

   getSubData: () => {
         let dbc = require('./mods/db.js');
         dbc.query(`

         SELECT 10 rn, 'Ten' rt UNION
         SELECT 20 rn, 'Twenty' rt UNION
         SELECT 30 rn, 'Thirty' rt ;

         `,
         function (err, rows) {
            if (err) {
              console.log ( ' Error 3: ' , err );
            } else {
               console.log ( 'arows: ', rows.length );
               return( rows );
            }
          })
   }

}

theapp.js:

let tm = require('./themod.js');

tm.getData();

When it's run:

 node theapp.js
/path/node/node_modules/mysql/lib/protocol/Parser.js:437
      throw err; // Rethrow non-MySQL errors
      ^

TypeError: Cannot read property 'length' of undefined
    at Query.<anonymous> (/path/node/themod.js:17:54)
    at Query.<anonymous> (/path/node/node_modules/mysql/lib/Connection.js:526:10)
    at Query._callback (/path/node/node_modules/mysql/lib/Connection.js:488:16)
    at Query.Sequence.end (/path/node/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
    at Query._handleFinalResultPacket (/path/node/node_modules/mysql/lib/protocol/sequences/Query.js:149:8)
    at Query.EofPacket (/path/node/node_modules/mysql/lib/protocol/sequences/Query.js:133:8)
    at Protocol._parsePacket (/path/node/node_modules/mysql/lib/protocol/Protocol.js:291:23)
    at Parser._parsePacket (/path/node/node_modules/mysql/lib/protocol/Parser.js:433:10)
    at Parser.write /path/node/node_modules/mysql/lib/protocol/Parser.js:43:10)
    at Protocol.write (/path/node/node_modules/mysql/lib/protocol/Protocol.js:38:16)

As requested, mods/db.js:

var mysql = require('mysql');

var dbConn = mysql.createConnection({
   host     : 'localhost',
   user     : 'unam',
   password : 'pwrd',
   database : 'dbname'
});

dbConn.connect ( function(err) {
   if (err) {
      console.error( "DB Connect failed ", err);
   }
});

module.exports = dbConn;

答案1

得分: 0

I think your problem comes from the scope of your getSubData function.

你的问题可能来自于 getSubData 函数的作用域。

You do not return anything; you return rows in the callback function, but nothing at the getSubData level.

你没有返回任何东西;你在回调函数中返回了行,但在 getSubData 层级中没有返回任何东西。

That's why it returns null, and then .length cannot be read.

这就是为什么它返回 null,然后无法读取 .length

You can try with this:

你可以尝试使用这个:

getSubData: () => {
    let dbc = require('./mods/db.js');
    return dbc.query(`
        SELECT 10 rn, 'Ten' rt UNION
        SELECT 20 rn, 'Twenty' rt UNION
        SELECT 30 rn, 'Thirty' rt ;
    `,
    function (err, rows) {
        if (err) {
            console.log('Error 3:', err);
        } else {
            console.log('rows:', rows.length);
            return rows;
        }
    })
}

You will then get the full query and the result inside.

然后,你将在内部获得完整的查询和结果。

So regarding functions synchronization, you are good; it is more a matter of scope.

所以,关于函数同步,你是正确的;这更多是关于作用域的问题。

This example should work:

这个示例应该可以工作:

const function1 = () => {
    const function2 = () => {
        return 'something';
    }
    return function2;
}

You wrote:

你写的是:

const function1 = () => {
    const function2 = () => {
        return 'something';
    }
    //nothing returned for function1
}
英文:

I think your problem come from the scope of your getSubData function.

You do not return anything, you return row in the callback function but nothing at the getSubData level.
That's why arrow return null and then .length cannot be red.

You can try with this

   getSubData: () => {
         let dbc = require('./mods/db.js');
         return dbc.query(`

         SELECT 10 rn, 'Ten' rt UNION
         SELECT 20 rn, 'Twenty' rt UNION
         SELECT 30 rn, 'Thirty' rt ;

         `,
         function (err, rows) {
            if (err) {
              console.log ( ' Error 3: ' , err );
            } else {
               console.log ( 'arows: ', rows.length );
               return( rows );
            }
          })
   }

you will then get the full query and the result inside.

So regarding functions synchronization you are good it is more a matter of scope.
This example should work :

const function1 = () => {
    const function2 = () => {
        return 'something'
    }
    return function2
}

Your wrote

const function1 = () => {
    const function2 = () => {
        return 'something'
    }
    //nothing returned for function1
}

huangapple
  • 本文由 发表于 2023年5月22日 04:55:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76301890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定