Javascript Node + Sequelize:如何在添加之前检查项目是否存在?(异步混乱)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31815076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:13:42  来源:igfitidea点击:

Node + Sequelize: How to check if item exists before adding? (async confusion)

javascriptnode.jsasynchronoussequelize.jsasync.js

提问by waffl

I am unfortunately new to node and running into some confusion regarding the asynchronous/synchronous execution of node.

不幸的是,我是 node 的新手,并且在 node.js 的异步/同步执行方面遇到了一些困惑。

I am using node, sequelize with sqlite and async.js.

我正在使用节点,使用 sqlite 和 async.js 进行续集。

I have a series of Articles, each of which has a number of Authors.

我有一系列的Articles,每个都有一些Authors

For each Authorsin each Article, I'd like to check if the Authorexists. If not, create it.

对于每个Authors中的每个Article,我想检查是否Author存在。如果没有,请创建它。

The problem is, on the initial run, duplicate authors are being created, I assume due to asynchronous functionality causing an issue with checking for existence.

问题是,在初始运行时,正在创建重复的作者,我假设是由于异步功能导致检查存在问题。

For example, with the array: authors = ['A. Test', 'B. Test', 'C. Test', 'A. Test']

例如,使用数组: authors = ['A. Test', 'B. Test', 'C. Test', 'A. Test']

and the code:

和代码:

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()
          })
        }
      })
    })
  })

On the first run, will create a table:

在第一次运行时,将创建一个表:

ID | name
------------
0  | A. Test
1  | B. Test
2  | C. Test
3  | A. Test

What am I doing wrong? I seem to be missing a fundamental concept of asynchronous vs synchronous execution in Node.

我究竟做错了什么?我似乎缺少 Node.js 中异步与同步执行的基本概念。

(I've also tried async.eachSeries which is supposed to execute in series rather than in parallel?)

(我也试过 async.eachSeries 应该串行执行而不是并行执行?)

Edit: Slightly refactored, but still creating duplicates

编辑:稍微重构,但仍然创建重复

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()
        })
      }
    })
  })

回答by Joshua F

Author.countisn't really needed, unless you needthe count. See findOrCreate().

Author.count不是真的需要,除非你需要计数。请参阅findOrCreate()

With findOrCreate()you could have the following. (Edited trex005's snippet for this)

有了findOrCreate()你可以有以下。(为此编辑了 trex005 的片段)

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();
    });
  })
})

回答by trex005

Change your each to eachSeriesand actually call the callback and you should be golden.

将您的 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();
          })
        }
      })
    })
  })