提问人:Howl 提问时间:2/6/2022 更新时间:2/6/2022 访问量:81
用解析文本文件的 after promise 填充数据库
Filling a database with after promises parsing a text file
问:
我正在尝试使用 bluebird 和 sqlite3 构建一个数据库来管理很多“成分”。 到目前为止,我已经设法解析了一个文件,并使用正则表达式从中推断出一些数据。
每当一行与正则表达式匹配时,我都想在数据库中搜索是否已经插入了同名元素,如果是这样,则跳过该元素,否则必须插入。 问题在于某些元素入了不止一次。 代码部分有效,我说它部分有效,因为如果我删除检查是否存在同名元素的代码行,重复的行会多得多。
下面是这段代码:
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)
}
})
}
});
我知道我错过了一些关于承诺的东西,但我不明白我做错了什么。
下面是 Both 和 的代码: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]
)
}
答:
0赞
Ivan Bacher
2/6/2022
#1
ingredientsRepo.getByName(matchedName)
返回一个 promise,这意味着它是异步的。我也猜测这是异步的,因为您正在将某些内容插入到数据库中。ingredientsRepo.create(matchedName)
循环不会等待这些异步函数完成。因此,当第一次迭代调用 时,循环可能已经在第 50 次迭代中出现。.then(...)
因此,假设前 10 个元素具有相同的名称。好吧,由于异步函数需要一些时间才能完成,因此在循环的第 20 次迭代之前,该名称不会插入到数据库中。因此,对于前 10 个元素,该名称在数据库中不存在。
这是一个时机问题。
评论
0赞
Howl
2/6/2022
我是这么认为的,我尝试使用 ''' await ingredientsRepo.getByName(matchedName)...''' 调用 getByName wait,但它没有改变 reuslt
0赞
Ivan Bacher
2/7/2022
我认为这行不通。通过添加 await,您所做的只是在您传入的回调中返回一个 promise。它不会等待它完成,然后再进入下一个迭代。看看 async.js,特别是队列或瀑布控制流技术。lineReader.eachLine()
评论