Node.js异步数据库查询函数报错问题及正确返回结果的实现方案咨询
Hey there! Let's break down what's going wrong with your code and fix it step by step, plus cover some cleaner approaches for async database queries in Node.js.
What's Broken in Your Current Code
Misplaced Promise Resolve
You’re passing the return value ofcon.query()directly toresolve(), butcon.queryis callback-based—it doesn’t return the database results immediately. Your Promise resolves right away (before the query finishes) with whatevercon.queryreturns (usually a request object, not your data).Incorrect Error Handling
Throwing an error inside thecon.querycallback won’t be caught by your Promise. Promises usereject()to propagate errors, sothrowhere will just crash your app instead of lettingawaithandle it gracefully.Unnecessary
setTimeout
Unless you specifically need to delay the query by 1 second, this is just adding unnecessary latency—you can remove it entirely.
Fixed Version: Manual Promise Wrapping
Here’s how to adjust your code to properly wait for the database query and handle errors:
async function bringData() { // Pass both resolve AND reject to the Promise constructor return new Promise((resolve, reject) => { con.query('SELECT company, industry FROM my_table', function (err, result) { if (err) { console.error(err); // Use reject to pass errors to the Promise chain reject(new Error('Error getting data from google_businesses table')); } else { // Resolve ONLY when we have the actual query result resolve(result); } }); }); } (async () => { // Wrap await in try/catch to handle errors from the Promise try { const getData = await bringData(); console.log(getData); } catch (err) { console.error('Failed to fetch data:', err.message); } })();
Cleaner Approach: Use util.promisify
Node.js has a built-in util.promisify tool that converts callback-based functions to Promise-based ones, so you don’t have to wrap the query manually:
const util = require('util'); // Convert con.query to a Promise-based function (bind preserves the connection context) const queryAsync = util.promisify(con.query).bind(con); async function bringData() { try { // Now we can await the query directly const result = await queryAsync('SELECT company, industry FROM my_table'); return result; } catch (err) { console.error(err); throw new Error('Error getting data from google_businesses table'); } } (async () => { try { const getData = await bringData(); console.log(getData); } catch (err) { console.error('Failed to fetch data:', err.message); } })();
Best Practice: Use a Promise-Native Database Driver
Even better, switch to a database driver that supports Promises natively (like mysql2/promise), which eliminates the need for promisify entirely:
First install the package:
npm install mysql2
Then rewrite your code:
const mysql = require('mysql2/promise'); // Create a connection (or use a connection pool for better performance) async function getDbConnection() { const connection = await mysql.createConnection({ host: 'your-db-host', user: 'your-db-user', password: 'your-db-password', database: 'your-db-name' }); return connection; } async function bringData() { const connection = await getDbConnection(); try { // execute() returns a Promise directly const [rows] = await connection.execute('SELECT company, industry FROM my_table'); return rows; } catch (err) { console.error(err); throw new Error('Error getting data from google_businesses table'); } finally { // Always close the connection when done await connection.end(); } } (async () => { try { const getData = await bringData(); console.log(getData); } catch (err) { console.error('Failed to fetch data:', err.message); } })();
Key Takeaways
- Always resolve/reject Promises inside the async callback when working with callback-based functions.
- Use
try/catchwithawaitto handle errors gracefully. - For cleaner code, prefer Promise-native tools or
util.promisifyover manual Promise wrapping.
内容的提问来源于stack exchange,提问作者HumzaXSN

