Node + Sequelize:如何在添加之前检查项目是不是存在? (异步混淆)
Posted
技术标签:
【中文标题】Node + Sequelize:如何在添加之前检查项目是不是存在? (异步混淆)【英文标题】:Node + Sequelize: How to check if item exists before adding? (async confusion)Node + Sequelize:如何在添加之前检查项目是否存在? (异步混淆) 【发布时间】:2015-10-27 04:48:15 【问题描述】:不幸的是,我是 node 新手,在 node 的异步/同步执行方面遇到了一些困惑。
我正在使用节点,使用 sqlite 和 async.js 进行续集。
我有一系列Articles
,每个都有一个Authors
的编号。
对于每个Article
中的每个Authors
,我想检查Author
是否存在。如果没有,请创建它。
问题是,在初始运行时,正在创建重复作者,我认为由于异步功能导致检查存在问题。
例如,使用数组:authors = ['A. Test', 'B. Test', 'C. Test', 'A. Test']
和代码:
async.each(authors, function(item, callback)
Author.sync().then(function()
Author.count( where: name: item.trim() ).then(function(count)
if (count != 0)
console.log('Author already exists')
else
console.log('Creating author...')
Author.create(
name: item.trim()
)
)
)
)
在第一次运行时,将创建一个表:
ID | name
------------
0 | A. Test
1 | B. Test
2 | C. Test
3 | A. Test
我做错了什么?我似乎错过了 Node 中异步与同步执行的基本概念。
(我也尝试过 async.eachSeries 应该串行执行而不是并行执行?)
编辑:略微重构,但仍然创建重复项
async.eachSeries(authors, function(authorName, callback)
Author.findOne( where: name: authorName.trim() ).
then(function(author)
if (author)
// Author exists...
callback()
else
// Author does not exist...
Author.create(
name: authorName.trim()
).then(function(author)
callback()
)
)
)
【问题讨论】:
【参考方案1】:将你的 each 更改为 eachSeries
并实际调用回调,你应该是黄金。
async.eachSeries(authors, function(item, callback)
Author.sync().then(function()
Author.count( where: name: item.trim() ).then(function(count)
if (count != 0)
console.log('Author already exists')
callback(); //assuming you want it to keep looping, if not use callback(new Error("Author already exists"))
else
console.log('Creating author...')
Author.create(
name: item.trim()
).then(function(author)
callback();
)
)
)
)
【讨论】:
嗯,这似乎不起作用,它只是在添加第一作者。 您的 Author.create 是否支持我在 cmets 中提到的回调? 对不起,你是什么意思?create
方法是 implemented by sequelize,这会产生一个承诺
好的,可以了,谢谢!只是为了澄清我对流程的理解,调用的callback()
函数是什么?我发现async.js documentation 的措辞令人困惑。
它告诉循环继续【参考方案2】:
Author.count
并不是真正需要的,除非您需要计数。见findOrCreate()。
使用findOrCreate()
,您可以拥有以下内容。 (为此编辑了trex005的sn-p)
async.eachSeries(authors, function(item, callback)
Author.sync().then(function()
Author.findOrCreate(
where:
name: item.trim()
,
defaults: // set the default properties if it doesn't exist
name: item.trim()
).then(function(result)
var author = result[0], // the instance of the author
created = result[1]; // boolean stating if it was created or not
if (!created) // false if author already exists and was not created.
console.log('Author already exists');
console.log('Created author...');
callback();
);
)
)
【讨论】:
您好,感谢您的回复,实际上我尝试了findOrCreate
(并重构为添加到我上面的答案中的更简洁的 sn-p)但findOrCreate
导致了 sqlite 阻塞/的各种问题数据库锁定 - 显然这也发生在某些用户的 postgres 中。不幸的是,我的新 sn-p 仍然无法正常工作,并且仍在创建重复项。
@joshua-f 顺便说一句,您可以使用 spread 方法而不是 then 方法来分隔 promise 参数。示例:.spread(function(author, isCreated) ... );
@AliBARIN 哦,甜心,不知道。
在异步函数内部调用sync()是否有原因?
@RonenTeva 不,这可能应该在异步函数之外。以上是关于Node + Sequelize:如何在添加之前检查项目是不是存在? (异步混淆)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 MySql 中使用 sequelize 运行多个原始查询?
Node.js:如何在 Sequelize 中使用 Postgres 存储过程?