我在将多个元素批量插入表中时遇到问题,然后我立即从该表中获取最近插入的最后 X 个元素,但是当我这样做时,元素似乎还没有甚至以为我正在使用 async await 来等待异步操作,就已经完全插入了。
我正在做一个批量插入
const createElements = elementsArray => {
return knex
.insert(elementsArray)
.into('elements');
};
然后我有一个方法可以立即访问那些插入的 X 元素:
const getLastXInsertedElements = (userId, length, columns=['*']) => {
return knex.select(...columns)
.from('elements').where('userId', userId)
.orderBy('createdAt', 'desc')
.limit(length);
}
最后,在获取这些元素后,我获取了它们的 ID 并将它们保存到另一个表中,该表使用最近添加的元素的 element_id。
所以我有类似的东西:
// A simple helper function that handles promises easily
const handleResponse = (promise, message) => {
return promise
.then(data => ([data, undefined]))
.catch(error => {
if (message) {
throw new Error(`${message}: ${error}`);
} else {
return Promise.resolve([undefined, `${message}: ${error}`])
}
}
);
};
async function service() {
await handleResponse(createElements(list), 'error text'); // insert x elements from the list
const [elements] = await handleResponse(getLastXInsertedElements(userId, list.length), 'error text') // get last x elements that were recently added
await handleResponse(useElementsIdAsForeignKey(listMakingUseOfElementsIds), 'error text'); // Here we use the ids of the elements we got from the last query, but we are not getting them properly for some reason
}
所以问题:
有时当我执行 getLastXInsertedElements
时,似乎 elements
还没有完成插入,甚至以为我正在等待 async/await ,知道这是为什么吗?也许与我不知道的批量插入有关?一个重要的注意事项,所有元素总是在某个时候正确地插入到表中,似乎这一点没有得到 promise 的尊重(为 knex.insert 返回成功的异步操作)。
更新 1: 为了测试目的,我尝试将插入后的选择放在 5 秒的 setTimeout 内,但问题似乎仍然存在,这真的很奇怪,似乎有人会认为插入和选择之间的 5 秒足以获取所有数据.
我希望所有刚刚插入的 X 元素都可以在 getLastXInsertedElements
的选择查询中一致地访问。
最佳答案
您正在使用哪个数据库,您要插入多大的数据列表?您还可以测试是否在事务中插入和 getLastXInsertedElements
如果这隐藏了您的问题。
在事务中执行这些操作还会强制 knex
对两个查询使用相同的连接,因此它可能会导致跟踪这是从哪里来的。
强制查询使用相同连接的另一个技巧是将池的最小和最大配置设置为 1(仅用于测试并行性确实是这里的问题)。
此外,由于您没有为此提供完整的重现代码,我怀疑这里还有其他东西导致了这种奇怪的行为。通常(但不总是)这种不应该发生的奇怪情况是由用户在其他地方使用该库的错误引起的。
如果提供了更多信息,我会更新答案。完整的复制代码将是最重要的信息。
关于javascript - Knex 批量插入在传递到下一个异步操作之前不等待它完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62338510/