在Nodejs中使用promise和orm
在Nodejs中使用promise和orm
前阵子做的项目中,字段比较多,初学node代码写的很混乱,最终成了酱紫:
现在准备重构这个项目,callback用promise替代,用orm替代手写sql语句,这里有两个问题:
- nodejs中大部分操作是回调式的,假设使用Q的话,是否要用
.defered()
方法在函数入口处promise化,然后继续逻辑处理? - orm搜了一下,发现start最多的式 http://sequelizejs.com/,准备翻翻文档用起来,orm除了无需手写sql之外还有什么好处吗?目前有哪些开源项目使用了orm+promise?
tks
在Nodejs中使用Promise和ORM
前言
在最近的一个项目中,我负责处理的数据库操作非常复杂,涉及大量的字段。由于对Node.js还不太熟悉,最初采用的回调方式导致代码变得非常混乱。因此,我决定重构这部分代码,将回调函数替换为Promises,并使用ORM来简化SQL语句的编写。
问题1:使用Q库时是否需要手动Promise化?
在Node.js中,很多操作都是异步的,通常使用回调函数来处理异步结果。如果你选择使用Q库(一个流行的Promise库),那么确实需要将这些回调函数Promise化。这可以通过Q.defer()
方法实现,它允许你创建一个新的Promise对象并手动解决或拒绝该Promise。
示例代码:
const Q = require('q');
function readFile(filePath) {
let deferred = Q.defer();
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) {
deferred.reject(err);
} else {
deferred.resolve(data);
}
});
return deferred.promise;
}
在这个例子中,readFile
函数返回一个Promise,而不是使用传统的回调函数。
问题2:关于ORM的选择和好处
ORM(Object-Relational Mapping)是一种编程技术,用于将关系型数据库中的数据与对象进行映射。使用ORM可以极大地简化SQL语句的编写,提高开发效率。Sequelize是一个非常流行且功能强大的ORM库,它支持多种数据库,包括MySQL、PostgreSQL等。
Sequelize的基本用法:
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'
});
const User = sequelize.define('User', {
name: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
}
}, {
timestamps: false
});
// 使用Promise来处理数据库操作
User.create({ name: 'John Doe', email: 'john@example.com' })
.then(user => console.log(`User created: ${user.name}`))
.catch(err => console.error('Error creating user:', err));
ORM的好处:
- 简化SQL语句编写:ORM自动处理SQL语句的生成,减少出错的可能性。
- 更好的数据抽象:ORM提供了面向对象的数据模型,使代码更易于理解和维护。
- 事务管理:ORM提供了事务管理的支持,确保数据的一致性。
- 类型安全:通过定义数据模型,可以确保数据类型的一致性和完整性。
开源项目示例: 一些知名的开源项目已经使用了ORM + Promise组合,例如:
- Ghost博客平台:使用Sequelize ORM和Promise来处理数据库操作。
- Mongoose:虽然主要用于MongoDB,但也是一个基于Promise的ORM。
希望以上内容对你有所帮助!如果你有更多问题,欢迎随时提问。
结尾
通过使用Promises和ORM,可以显著提高代码的可读性和可维护性。希望我的经验分享能帮助你在未来的项目中更好地利用这些工具。
promise 不懂,我喜欢用 eventproxy,用事件思想来解耦比较好懂。
promise库推荐bluebird,现在promise库大部分都支持对node格式的回调进行直接转换,不用再手动处理了,比如bluebird提供的Promise.promisify接口
使用bluebird吧,我也是最近重构自己的代码,换了bluebird
最近在写一个非常简陋的支持 memcached 绑定的 ORM,查询兼容 callback 和 promise 模式。
看到这么多回调吓鸟了, 还是感觉用Promise模块好
重构完成后,首页是酱紫的:
ListAll()
是定义在model中的方法,路由的逻辑被Controller层handle,简直酸爽
:-O 我好喜欢工工整整的代码。
以前写过的一个答案:如何用nodejs 把业务逻辑写的漂亮
Q太重了 硬是要用promise的话 推荐when.js 不过你还可以试试 co,把node版本升级到0.12+
用yield处理回调呀,tj大神的co很好用的,node v0.11版本 支持 es6 的yield,再用koajs就好极了,哈哈,另外我自己是觉得没必要非要搞个orm,自己写个sql模板,把sql和js代码分离出来,用的时候用参数填充下sql模板,又轻量又简洁。
用bluebird 怎么重构上面的例子?求大神
orm直接支持promise写起数据层来就比较舒服了.然而promise还是有弊端.如果对promise的机理不甚了解的话可能会造成"知其型不知其意",导致看得懂代码改不了代码的困境.我最喜欢promise的地方是他的错误处理,所有显性和隐性的错误都可以捕获,而回调的话隐形的错误处理会比较不好处理.
啊强的ep 自豪地采用 CNodeJS ionic
async语法糖简单点,如果你不学promise的话
sequelize 自豪地采用 CNodeJS ionic
强推一个牛逼架构,onela,node.js使用npm install onela安装。需要稍微配置下,强大之处就是支持分布式数据库,而且支持读写分离,配合分布式缓存应用直接可以跑中大型应用灵活度相当高。架构预设了多种类型的数据库支持(不过目前只开放了mysql部分),跨数据库无SQL编程,可以很好的跟自有分布式缓存结合,开发高性能应用完全有潜力,实现本地事务,后续结合消息队列感觉能继续迭代分布式事务。开发人员只关注业务逻辑部分,另外这套ORM框架是基于Promise实现整套架构,链式方法结构避免了令人呕吐callback,写法相当优雅。 GitHub: https://github.com/zouwei/onela npm: https://www.npmjs.com/package/onela 在架构内部内置了初始化配置的工具方法,一键初始化配置文件,后台常用的增删改查快速模板化生成代码,爽的不要不要的。
针对你的问题,我将分两部分进行回答。
1. 使用Promise替代Callback
在Node.js中,Q
是一个非常流行的Promise库。你可以使用 .deferred()
方法来创建一个新的Promise对象,并在异步操作完成后调用 resolve
或 reject
方法。这是一个简单的示例:
const Q = require('q');
function getUser(id) {
let deferred = Q.defer();
// 模拟数据库查询
setTimeout(() => {
if (id > 0) {
deferred.resolve({ id: id, name: 'John Doe' });
} else {
deferred.reject(new Error("Invalid user ID"));
}
}, 1000);
return deferred.promise;
}
// 使用 .then() 和 .catch() 处理Promise
getUser(1)
.then(user => console.log(user))
.catch(err => console.error(err));
2. 使用ORM替代SQL
Sequelize
是一个强大的ORM库,它可以让你通过定义模型(Model)来操作数据库表,从而避免直接编写SQL语句。它的好处包括:
- 类型安全:通过定义模型属性类型,可以避免运行时错误。
- 链式API:提供链式方法来构建复杂的查询。
- 事务管理:可以方便地处理事务。
- 关系映射:支持表之间的关联,如一对多、多对多等。
下面是一个简单的Sequelize使用示例:
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:'); // 使用内存数据库
const User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
allowNull: false
},
birthday: DataTypes.DATE
}, {});
// 同步数据库
(async () => {
await sequelize.sync({ force: true }); // 删除并重新创建表
// 创建新用户
const newUser = await User.create({
username: 'johndoe',
birthday: new Date(1980, 10, 20)
});
// 查询用户
const user = await User.findOne({ where: { username: 'johndoe' } });
console.log(user);
})();
开源项目使用ORM+Promise的例子
很多大型开源项目都采用了类似的架构,比如Express应用框架结合Sequelize ORM和Promise来管理数据操作。你可以查看一些知名的开源项目,如Ghost博客系统或KeystoneJS CMS,它们都是使用这些技术栈的典型例子。
希望这能帮助你更好地理解如何在Node.js项目中使用Promise和ORM。