Node.js(含npm mysql场景)如何用Async Await替代return new Promise?
Hey there! Let's break down how to swap out those return new Promise() calls with async/await in Node.js—especially when working with the npm mysql package. It's simpler than you might think, so let's dive in!
1. General: Replacing return new Promise() with Async/Await
First, let's cover the basics. Any function that returns a new Promise() can almost always be rewritten with async/await, since async functions automatically wrap their return values in a Promise.
Example: Original Promise-based function
function fetchSomeData() { return new Promise((resolve, reject) => { // Simulate an async operation (e.g., API call, timeout) setTimeout(() => { const success = true; if (success) { resolve("Here's your data!"); } else { reject(new Error("Oops, something went wrong")); } }, 1000); }); }
Rewritten with Async/Await
async function fetchSomeData() { // Wait for the async operation to complete await new Promise(resolve => setTimeout(resolve, 1000)); const success = true; if (success) { // Async functions auto-wrap this in a Promise return "Here's your data!"; } else { // Throwing an error will trigger the Promise's catch() throw new Error("Oops, something went wrong"); } }
Key takeaways here:
- Add the
asynckeyword to the function definition to enable await support - Use
awaitto pause execution until the async operation finishes - Return values automatically become the resolved value of the function's Promise
- Thrown errors act as the rejected value (replacing
reject()calls)
2. Specific: Node.js + npm mysql Package
The standard mysql package uses callbacks by default, so you might have wrapped connection.query() in a new Promise() to use it with promises. Let's fix that with async/await.
Option 1: Promisify the query method with util.promisify
Node.js has a built-in util.promisify tool that converts callback-based functions to return Promises. Here's how to use it:
const util = require('util'); const mysql = require('mysql'); // Create your database connection const connection = mysql.createConnection({ host: 'localhost', user: 'your_username', password: 'your_password', database: 'your_database' }); // Convert connection.query to return a Promise connection.query = util.promisify(connection.query); // Now write your async function async function getUserById(userId) { try { // Use await instead of wrapping in a Promise const results = await connection.query('SELECT * FROM users WHERE id = ?', [userId]); return results[0]; // Return the first matching user } catch (error) { // Handle or rethrow the error (matches the old reject() behavior) throw new Error(`Failed to fetch user: ${error.message}`); } }
Option 2: Use mysql2 (Promise-native alternative)
If you're open to switching packages, mysql2 has a built-in Promise API that makes this even smoother. Install it first with npm install mysql2, then:
const mysql = require('mysql2/promise'); async function getUserById(userId) { // Create a connection (or use a pool for production) const connection = await mysql.createConnection({ host: 'localhost', user: 'your_username', password: 'your_password', database: 'your_database' }); try { // Execute the query directly with await const [results] = await connection.execute('SELECT * FROM users WHERE id = ?', [userId]); return results[0]; } catch (error) { throw new Error(`Failed to fetch user: ${error.message}`); } finally { // Always close the connection when done await connection.end(); } }
Bonus: Connection Pools for Production
For production apps, connection pools are more efficient than single connections. Here's how to use them with async/await (using mysql2):
const mysql = require('mysql2/promise'); // Create a reusable connection pool const pool = mysql.createPool({ host: 'localhost', user: 'your_username', password: 'your_password', database: 'your_database', connectionLimit: 10, // Adjust based on your needs waitForConnections: true }); async function getUserById(userId) { // Grab a connection from the pool and run the query const [results] = await pool.execute('SELECT * FROM users WHERE id = ?', [userId]); return results[0]; }
Quick Recap
- Mark your function as
asyncto enable await and auto-Promise wrapping - Use
awaitfor any async operation that returns a Promise - Replace
reject()withthrowand handle errors withtry/catch - For callback-based libraries like
mysql, useutil.promisifyor switch to a Promise-native version likemysql2
内容的提问来源于stack exchange,提问作者Dave Chambers

