mysql - 使用 Expressjs 和 mysql 的 API 的 MVC 模式`未定义不是函数`
问题描述
我正在使用 Node、Express、MySQL 构建 API 端点,简化如下,当访问/orders
路由时,API 崩溃并出现错误undefined is not a function
(有关错误和代码片段中回溯的更多详细信息):
注意:以下所有模型都扩展了 BasicModel
// /connection/connection.js
import mysql from 'mysql'
import env from '../env.js'
export default mysql.createPool({
port : env.DB_PORT,
connectionLimit : env.DB_CONNECTION_LIMIT,
user : env.DB_USER,
password : env.DB_PASSWORD,
database : env.DB_NAME
})
// /routes/v1/orders.js
import { Router } from 'express'
import OrdersController from '../../controllers/OrdersController.js'
const router = Router()
const controller = new OrdersController
// I have a router.js that builds my routes based on my file structure
// so the following GET is equivalent to get(`/v1/orders/`)
router.get('/', controller.all)
export default router
// /controllers/ControllerCommons.js
export default class ControllerCommons {
all = (req, res) => {
this.model.all(data => {
res.json(data)
})
}
byId = (req, res) => {
const id = parseInt(req.params.brands_id)
this.model.byId(id, data => res.json({data}))
}
}
// /controllers/OrdersController.js
import OrdersModel from '../models/OrdersModel.js'
import ControllerCommons from './ControllerCommons.js'
export default class OrdersController extends ControllerCommons{
model = new OrdersModel
}
// /models/BasicModel.js
import conn from '../connection/connection.js'
export default class BasicModel {
all(callback = _ => null) {
const sql = 'SELECT * FROM ??'
conn.query(sql, [this.table], function(err, result) {
if (err) return callback(err)
callback(result)
})
}
byId(id, callback = _ => null) {
const sql = 'SELECT * FROM ?? WHERE id=?'
conn.query(sql, [this.table, id], function(err, result) {
if (err) return callback(err)
callback(result)
})
}
// /models/OrdersModel.js
export default class OrdersModel extends BasicModel {
table = 'vr_vendors_orders'
all(callback = _ => null) {
super.all((data) => {
data.forEach((order, index) => { // data has 100+ records
const statusId = order.status_id
const vendorId = order.vendors_id
const currencyId = order.currency_id
this.vendor(vendorId, (vendorResponse) => {
// Response is 1 row, 12 fields big (vendorResponse.length === 12)
order['vendor'] = vendorResponse
delete order.vendors_id
})
this.status(statusId, (statusResponse) => {
// Response is 1 row, 3 fields big (statusResponse.length === 3)
order['status'] = statusResponse
delete order.status_id
})
this.currency(currencyId, (currencyResponse) => {
// Response is 1 row, 3 fields big (currencyResponse.length === 3)
order['currency'] = currencyResponse
delete order.currency_id
})
if (index === data.length - 1) {
callback(data)
}
})
})
}
vendor = (vendorId, callback = _ => null) => {
const vendorsModel = new VendorsModel
vendorsModel.byId(vendorId, ([vendor]) => {
callback(vendor)
})
}
status = (statusId, callback = _ => null) => {
const statusesModel = new StatusesModel
statusesModel.byId(statusId, ([status]) => {
callback(status)
})
}
currency = (currencyId, callback = _ => null) => {
const currencyModel = new CurrencyModel
currencyModel.byId(currencyId, ([currency]) => { //<----- undefined is not a function Ln:[whatever line this is], Col:40
callback(currency)
})
}
}
问题
- 知道为什么会发生错误吗?(注意:所有数据项都有有效的ID)
- 任何想法如何改进其构建方式以防止这种情况再次发生?我讨厌我像 eHonda 100 Hand Slap 一样循环访问数据库中的 100 多个项目(我相信
TRANSACTION
或者LEFT JOIN
会更推荐)有什么想法吗? join()
关于如何在 my上构建方法的想法ControllerCommons.js
?- 对使用
Promisify
,TRANSACTION
和/或LEFT JOIN
(带有nestTables
选项)的想法?你觉得它会解决问题吗? - 小花絮:更改我在方法中访问数组项的
currency
方式(是的,仅当我将更改应用于currency
方法时才有效)可防止 API 崩溃,但有时它工作正常,有时order['status']
为空,有时它根本没有创建:
// currencyModel.byId(currencyId, ([currency]) => { //<----- undefined is not a function Ln:[whatever line this is], Col:40
// callback(currency)
// })
currencyModel.byId(currencyId, (result) => { // not destructing the array, prevents the crash... but why? Performance? And why just for this method?
const currency = result[0]
callback(currency)
})
想法?