Node.js MVC项目中无法从Model获取返回值至Controller的问题求解
Hey there! Let's troubleshoot why your user model's data isn't making its way to the controller in your Node.js MVC project. This is a super common issue tied to how Node handles async operations, so let's break down the key fixes step by step.
1. You're Not Handling Async Operations Correctly
Nearly all database calls (and most I/O in Node) are asynchronous. If your model method tries to return data synchronously, you'll get a Promise/callback object instead of actual results.
Bad Model Example (Synchronous Return)
// models/users.js (WRONG) exports.getUsers = () => { // db.query is async—this returns a query object, not results! const data = db.query('SELECT * FROM users'); return data; };
Fix 1: Use Callbacks
If your database library uses callbacks, pass the result up to the controller via a callback:
// models/users.js (CORRECT with callbacks) exports.getUsers = (callback) => { db.query('SELECT * FROM users', (error, results) => { if (error) return callback(error); callback(null, results); }); }; // controllers/userController.js exports.getAllUsers = (req, res) => { require('../models/users').getUsers((err, users) => { if (err) return res.status(500).send('Database error'); res.status(200).json(users); }); };
Fix 2: Use Promises (Modern Approach)
Wrap your async logic in a Promise, or use a database library that supports Promises natively (like mysql2/promise or mongoose):
// models/users.js (CORRECT with Promises) exports.getUsers = () => { return new Promise((resolve, reject) => { db.query('SELECT * FROM users', (error, results) => { if (error) reject(error); else resolve(results); }); }); }; // Or with native Promise support (mysql2/promise) exports.getUsers = async () => { const [results] = await db.query('SELECT * FROM users'); return results; };
Then in your controller, use async/await to wait for the Promise to resolve:
// controllers/userController.js exports.getAllUsers = async (req, res) => { try { const users = await require('../models/users').getUsers(); res.status(200).json(users); } catch (err) { res.status(500).json({ error: err.message }); } };
2. You're Swallowing Errors in the Model
If your model catches an error but doesn't pass it to the controller, the controller will never know something went wrong—and might hang waiting for a result.
Bad Model Example (Error Swallowed)
// models/users.js (WRONG) exports.getUsers = async () => { try { const [results] = await db.query('SELECT * FROM users'); return results; } catch (err) { // Oops! Error is logged but not sent to the controller console.log('Error:', err); } };
Fix: Propagate Errors
Always re-throw errors in Promise/async functions, or pass them via callback:
// models/users.js (CORRECT) exports.getUsers = async () => { try { const [results] = await db.query('SELECT * FROM users'); return results; } catch (err) { // Send error to controller throw err; } };
3. Your Route-Controller-Model Connection is Broken
Double-check that your routes are correctly pointing to the controller methods, and that the controller is importing the model properly.
Example Correct Route Setup
// routes/users.js const express = require('express'); const router = express.Router(); const userController = require('../controllers/userController'); // Make sure this points to the right controller method router.get('/users', userController.getAllUsers); module.exports = router;
Quick Checklist to Debug
- Did you use
awaitwith async model methods in the controller? - Is your model returning a Promise or using callbacks correctly?
- Are errors being passed from model to controller (not swallowed)?
- Do your routes correctly reference the controller's methods?
内容的提问来源于stack exchange,提问作者rahul

