javascript - Knex 批量插入在传递到下一个异步操作之前不等待它完成

标签 javascript asynchronous async-await knex.js

我在将多个元素批量插入表中时遇到问题,然后我立即从该表中获取最近插入的最后 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/

相关文章:

javascript - 我可以这样做 : mysite. com?&var1=value1&var2=value2

c# - 将文本添加到 RichTextBox Async#C/WPF

python - 为什么需要等待 resp.text()?

javascript - Nodejs如何使用多个await promise

c# - Windows Azure 移动服务数据获取已完成

javascript - Jest Node.js 无法使用单独的文件正确调用 beforeAll 和 afterAll

javascript - Polymer通过javascript字符串绑定(bind)数据?

javascript - 异步AJAX按顺序调用

asynchronous - k6 http调用是异步的吗?

C# 等待 lambda 回调完成