You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js面向对象项目中正确使用Promise并优化架构

Hey Maxime! Great to see you bringing your PHP OOP experience over to Node.js—let's tackle your questions and get you set up with a solid structure and working code.


1. Is your current file structure following common best practices?

Your setup is a solid starting point, but we can refine it to align with Node.js ecosystem standards for maintainability:

  • Entry point: app.js as the main entry is totally fine.
  • Controllers vs Routes: Keep route definitions in /routes, but move your business logic classes to a dedicated /controllers folder. This separates endpoint mapping from request handling logic (a common Node.js pattern).
  • Model/Class files: Don’t put these in public/javascript—that folder is for frontend static assets (like client-side JS/CSS). Instead, create a /models folder for your Sequelize models and data access classes (like your User class).
  • Recommended structure example:
    project-root/
    ├── app.js          # Entry point: sets up server, middleware, and routes
    ├── controllers/    # Classes handling request/response logic
    ├── models/         # Sequelize models + database access methods
    ├── routes/         # Route definitions mapping endpoints to controllers
    ├── config/         # Database/configuration files
    └── node_modules/   # Dependencies
    

2. Implementing the Node.js + Class structure with Sequelize

The core issue you’re facing is misunderstanding how Sequelize handles Promises—methods like findAll() already return Promises, so you don’t need to wrap them in a new Promise unless you have extra logic to add. Let’s fix this with concrete examples:

Step 1: User Model/Class (in /models/User.js)

This class will encapsulate all user database operations:

const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database'); // Path to your Sequelize config

class User extends Model {
  // Static method to fetch all users
  static getAllUsers() {
    // Sequelize's findAll() returns a Promise—just return it directly!
    return this.findAll({
      // Add options like attributes, filters, or includes here
    });
  }

  // Add other methods like createUser, updateUser, or deleteUser here
}

// Initialize the model with your database schema
User.init({
  username: {
    type: DataTypes.STRING,
    allowNull: false
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true
  }
}, {
  sequelize,
  modelName: 'User'
});

module.exports = User;

Step 2: User Controller (in /controllers/UserController.js)

The controller handles request/response flow and calls the model’s methods:

const User = require('../models/User');

class UserController {
  // Async/await version (cleaner for readability)
  static async getUsers(req, res) {
    try {
      // Wait for the Promise from the model to resolve
      const users = await User.getAllUsers();
      res.status(200).json(users);
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  // .then() version (if you prefer chaining over async/await)
  // static getUsers(req, res) {
  //   User.getAllUsers()
  //     .then(users => res.status(200).json(users))
  //     .catch(error => res.status(500).json({ error: error.message }));
  // }
}

module.exports = UserController;

Step 3: Route Definition (in /routes/users.js)

Map HTTP endpoints to controller methods:

const express = require('express');
const router = express.Router();
const UserController = require('../controllers/UserController');

// GET all users
router.get('/', UserController.getUsers);

module.exports = router;

Step 4: Connect Routes to app.js

In your main entry file, mount the routes and start the server:

const express = require('express');
const app = express();
const userRoutes = require('./routes/users');

// Middleware to parse JSON requests
app.use(express.json());

// Mount user routes at /api/users
app.use('/api/users', userRoutes);

// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Fixing Your Original Promise Issue

Your earlier mistake was either not returning the Sequelize Promise from your class method, or trying to resolve an undefined Promise. By returning findAll() directly (which is already a Promise), you can use await or .then() to handle the result properly—no need to manually create a new Promise unless you’re adding custom logic before resolving.


Step-by-Step Guide for Node.js + ES6 OOP Projects (For Beginners)

Let’s turn this into a beginner-friendly walkthrough:

Prerequisites

  • Node.js installed
  • Basic knowledge of ES6 classes and Promises
  • A database (PostgreSQL, MySQL, etc.) set up

Step 1: Initialize the Project

  1. Create a project folder and navigate into it:
    mkdir node-oop-demo && cd node-oop-demo
    
  2. Initialize npm:
    npm init -y
    
  3. Install dependencies:
    npm install express sequelize pg pg-hstore # Use mysql2 instead of pg for MySQL
    npm install --save-dev nodemon # Auto-reloads server during development
    

Step 2: Set Up Sequelize

Create /config/database.js to configure your database connection:

const { Sequelize } = require('sequelize');

const sequelize = new Sequelize('your-db-name', 'your-db-username', 'your-db-password', {
  host: 'localhost',
  dialect: 'postgres' // or 'mysql'
});

// Test the connection
async function testConnection() {
  try {
    await sequelize.authenticate();
    console.log('Database connection successful!');
  } catch (error) {
    console.error('Connection failed:', error);
  }
}

testConnection();

module.exports = sequelize;

Step 3: Create Model Classes

Add your model files (like User.js) in /models as shown earlier.

Step 4: Build Controllers

Create controller classes in /controllers to handle request/response logic.

Step 5: Define Routes

Map endpoints to controller methods in /routes.

Step 6: Configure the Server

Set up Express in app.js, add middleware, and mount your routes.

Step 7: Run the Project

Add a script to package.json:

"scripts": {
  "start": "node app.js",
  "dev": "nodemon app.js"
}

Start the dev server:

npm run dev

内容的提问来源于stack exchange,提问作者Maxime OBLE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:18:05