Sequelize 是一个 Node.js 中非常流行的 ORM(对象关系映射)库,它允许开发者使用 JavaScript 语言操作关系型数据库。Sequelize 的 Promise 功能是其最常用的特性之一,它使得开发者可以将异步任务串联起来,降低代码的复杂度,从而提升应用的性能和效率。
什么是 Promise
Promise 是 JavaScript 中一种非常常见的异步编程的方式。Promise 是一种封装了具有异步执行能力的函数,并且可以使用链式语法调用的对象。一个 Promise 对象通常有 pending 状态、resolved 状态(也可以称为 resolved 成功状态)、rejected 状态(也可以称为 rejected 失败状态)三种状态。通过 then 方法,我们可以在 resolved 状态下执行一些操作,通过 catch 方法可以在 rejected 状态下执行一些错误处理。
举个例子,一个简单的 Promise 案例:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const message = 'Promise resolved!'
resolve(message)
}, 1000)
})
promise.then(message => console.log(message)).catch(err => console.error(err))上面的例子中,Promise 对象会在 1 秒后返回一个 resolved 状态,并打印出 Promise resolved! 的信息。
Sequelize 的 Promise 的使用
对于前端开发来说,Sequelize 支持使用 Promise 的方式执行数据库查询操作是非常值得称赞的。一个基本的 Sequelize 查询操作如下所示:
// www.javascriptcn.com code example
const User = sequelize.define('user', {
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING
}
});
(async () => {
await sequelize.sync()
const jane = await User.create({
firstName: 'Jane',
lastName: 'Doe'
})
console.log(jane.toJSON())
})()在上面的例子中,我们调用了 Sequelize 的 User.create 方法插入一条数据到 our 的 users 表中。但是这个操作是异步的,原因是在 Sequelize 内部执行了一个 Promise 对象。我们需要使用 await 关键字来等待操作返回结果。
当我们在查询操作后需要继续执行后续的操作时,这时候 Promise 的调用链式语法就可以大展拳脚了。比如我们需要查询(或者插入)多条数据之后进行一个分页展示,只要使用类似下面的方式即可:
// www.javascriptcn.com code example
User.findAll({
where: { lastName: 'Doe' },
offset: 10,
limit: 2
}).then(users => {
console.log(users)
}).catch(error => {
console.error(error)
})在操作中我们使用了 findAll 方法查询了表中 lastName 属性为 Doe 的数据,然后通过 offset 和 limit 给出要查询数据的起始位置和要查询的数据条数。Sequelize 并没有在查询过程中返回 Promise 实例,我们需要在 then (或者 catch)中获取到回调结果,并在 then 的回调中执行后续的操作。
Promise 的链式调用
我们也可以使用 Promise 的链式调用来实现多个异步任务的实现。在 Sequelize 中,我们可以使用 Promise 的 then 方法进行操作:
// www.javascriptcn.com code example
User.findOne().then(user => {
return user.updateAttributes({
firstName: 'tom'
})
}).then(() => {
console.log('update finished')
}).catch(error => {
console.error(error)
})在上面的例子中,我们首先使用 findOne 方法查询我们需要的 users 数据,查询会返回 Promise 对象,我们通过 then 方法来继续执行 Promise 对象的 updateAttributes 方法。在 updateAttributes 方法完成之后,我们再次使用 then 方法来进行后续的操作。我们还可以使用 catch 方法来处理可能出现的异常。
Sequelize 的 Promise 在应用中的优化
Sequelize 的 Promise 特性可以帮助我们在数据操作过程中可以更加高效地处理一些任务。比如在表与表之间的关联中,如果我们需要先查询一个表,然后使用查询结果再进行另外一个表的查询,当我们使用两个异步函数实现的时候,代码会看起来很冗长。例如,下面代码查询出一个用户的所有文章:
// www.javascriptcn.com code example
var getArticlesByUserId = function(userId) {
var user = null;
var articles = null;
sequelize.transaction(function (t) {
return model.user.findById(userId, {transaction: t}).then(function(_user) {
user = _user.get({ plain: true });
return model.articles.findAll({where: {userId: user.id}}, {transaction: t});
}).then(function(_articles) {
articles = _articles;
});
}).then(function () {
console.log(user.name + ' have articles:', articles.length);
}).catch(function (err) {
console.log(err);
});
};上面代码中的查询使用了一个嵌套的 Promise 结构来实现,使用 Sequelize 的 Promise 特性即可简化代码:
// www.javascriptcn.com code example
var getArticlesByUserId = function(userId) {
model.user.findById(userId).then(function(user) {
return user.getArticles();
}).then(function(articles) {
console.log(user.name + ' have articles:', articles.length);
}).catch(function(err) {
console.log(err);
});
};上面的代码的意思是首先查询 userId 对应的 user,然后直接使用 user.getArticles 方法查询 articles,可以看到上面代码中使用了链式调用的方式来实现异步函数的执行。这种代码实现方式看起来更加简洁、易懂,而且代码量也明显减少了。
结语
Promise 是 JavaScript 中一种非常常用的异步编程方式,Sequelize 的 Promise 特性可以使得开发者能够在数据操作过程中更高效地处理异步任务,减少代码冗长和复杂的问题。通过学习 Sequelize 的 Promise 特性,我们可以清晰地了解到如何使用 Promise 对象进行异步编程,从而让自己的代码更加高效、优雅。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d639d4a941bf7134beb8c3