【问题标题】:Filling a database with after promises parsing a text file用解析文本文件的承诺后填充数据库
【发布时间】:2022-02-06 03:08:09
【问题描述】:

我正在尝试使用 bluebird 和 sqlite3 构建一个数据库来管理很多“成分”。 到目前为止,我已经成功地解析了一个文件并使用正则表达式从中推断出一些数据。

每次一行匹配正则表达式时,我想在数据库中搜索是否已经插入了同名的元素,如果是,则跳过该元素,否则必须插入。 问题是某些元素被多次插入。 代码部分有效,我说它部分有效,因为如果我删除检查是否存在同名元素的代码行,重复的行会更多。 p>

这是一段代码:

 lineReader.eachLine(FILE_NAME, (line, last, cb) => {
      let match = regex.exec(line);
      if (match != null) {
          let matchedName = match[1].trim();

          //This function return a Promise for all the rows with corresponding name
          ingredientsRepo.getByName(matchedName)
             .then((entries) => {
                 if (entries.length > 0) {
                     console.log("ALREADY INSERTED INGREDIENT: " + matchedName)
                 } else {
                     console.log("ADDING " + matchedName)
                     ingredientsRepo.create(matchedName)
                 }
          })   
      }
 });

我知道我遗漏了一些关于 Promises 的内容,但我不明白我做错了什么。

这是getByName(name)create(name) 的代码:

create(name) {
    return this.dao.run(
        `INSERT INTO ingredients (name) VALUES (?)`,
        [name]
    )
}


getByName(name) {
    return this.dao.all(
        'SELECT * FROM ingredients WHERE name == ?',
        [name]
    )
}

【问题讨论】:

    标签: node.js sqlite promise bluebird


    【解决方案1】:

    ingredientsRepo.getByName(matchedName) 返回一个承诺,这意味着它是异步的。我也猜想ingredientsRepo.create(matchedName) 是异步的,因为你正在向数据库中插入一些东西。

    您的循环不会等待这些异步函数完成。因此,循环可能已经在第 50 次迭代中,此时第一次迭代调用了 .then(...)

    假设前 10 个元素具有相同的名称。好吧,由于异步函数需要一些时间才能完成,所以直到循环的第 20 次迭代才会将名称插入数据库。所以对于前 10 个元素,名称在 DB 中不存在。

    这是时间问题。

    【讨论】:

    • 我应该是这样的,我尝试使用 ``await ingredientsRepo.getByName(matchedName)...``` 调用 getByName 等待,但它并没有改变结果
    • 我认为这行不通。通过添加等待,您所做的就是在您传递给lineReader.eachLine() 的回调中返回一个承诺。在进入下一次迭代之前,它不会等待它完成。看看async.js,特别是队列或瀑布控制流技术。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多