Node.js中基于OOP将数据库查询回调转为async/await实现求助
Got it, let's fix up your callback-heavy code to use async/await while preserving your existing OOP structure. This will make your code far more readable and maintainable as your project scales—no more callback nesting chaos!
First, let's address the core issues: your current name method relies on callbacks, which gets messy fast. We'll convert it to return a Promise (which works seamlessly with async/await), and also fix a critical SQL injection vulnerability in the process.
Step 1: Update object.js
We'll rewrite the name method to be async, wrapping the MySQL query in a Promise. We'll also use parameterized queries to avoid SQL injection (never concatenate user input directly into SQL strings!):
// object.js module.exports = class { constructor(userID) { this.id = userID; } // Convert to async method that returns a Promise async name() { return new Promise((resolve, reject) => { // Use parameterized query to prevent SQL injection mysqli.query("SELECT meno FROM uzivatelia WHERE id=?", [this.id], (err, user) => { if (err) { // Reject the Promise if there's an error return reject(err); } // Resolve with the username if successful resolve(user[0].meno); }); }); } };
Bonus: Use MySQL's Promise-Based API (Even Cleaner!)
If you switch to mysql2/promise (a popular promise-aware alternative to the standard mysql package), you can skip manual Promise wrapping entirely:
// object.js (using mysql2/promise) const mysql = require('mysql2/promise'); // Assume you've created a connection pool or client instance const mysqli = mysql.createPool({ /* your db config */ }); module.exports = class { constructor(userID) { this.id = userID; } async name() { // Query returns an array [results, fields] const [user] = await mysqli.query("SELECT meno FROM uzivatelia WHERE id=?", [this.id]); return user[0].meno; } };
Step 2: Update server.js
Now we can use await to call the async name method. Since await can only be used inside an async function, we'll use an immediately-invoked async function expression (IIFE) to run our code:
// server.js const object = require("./object"); // Replace the callback with an async IIFE (async () => { try { const user = new object(userID); const userName = await user.name(); console.log(userName); } catch (err) { // Handle any errors (e.g., database issues, no user found) console.error("Failed to fetch username:", err); } })();
Key Improvements
- Readability: Code flows linearly instead of nesting callbacks, making it easier to follow logic as your project grows.
- Error Handling: Centralized
try/catchreplaces scattered error checks in callbacks, making it simpler to handle failures consistently. - Security: Parameterized queries eliminate SQL injection risks that were present in your original code.
- Maintainability: Async/await integrates smoothly with OOP patterns, so you can keep using classes while avoiding callback hell.
内容的提问来源于stack exchange,提问作者Styx25

