【问题标题】:Knex Inserting Same Record Twice when Query Executed AsynchronouslyKnex 在异步执行查询时插入相同的记录两次
【发布时间】:2018-05-11 08:28:52
【问题描述】:

在我的/api/v1/chats POST 路由中,我为请求正文中传递的每个user_id 进行异步调用user_chat_queries.addUserChat。这个想法是,如果有很多 user_id 进来,我不想让每个插入 await,而是我想异步调度所有插入,所以我这样做:

异步路由处理程序(https://github.com/caseysiebel/lang-exchange/blob/master/src/server/routes/chats.js#L57):

await Promise.all(user_ids.map((user_id) => {
    return user_chat_queries.addUserChat(user_id, chat.id)
}));

相反,

同步:

for (let user_id of user_ids) {
    await user_chat_queries.addUserChat(user_id, chat.id)
}

而在user_chat_querieshttps://github.com/caseysiebel/lang-exchange/blob/master/src/server/db/queries/user_chat.js#L5):

addUserChat: ( async (user_id, chat_id) => {
    const user_chat = await userChats
        .insert({ user_id, chat_id })
        .returning('*')
    const data = await db('user_chat').select('*')
    return user_chat;
}),

现在从我的测试文件访问路由:(https://github.com/caseysiebel/lang-exchange/blob/master/test/routes.chats.test.js#L83)

it('should add 2 user_chats', (done) => {
    chai.request(server)
        .post('/api/v1/chats')
        .send({
            created_at: Date.now(),
            user_ids: [ 2, 4 ]
        })
        .end((err, res) => {
            should.not.exist(err);
            res.status.should.equal(201);
            res.type.should.equal('application/json');
            res.body.status.should.eql('success');
            const chat = res.body.data;
            chat.should.include.keys('id', 'created_at');

            knex('user_chat')
                .select('*')
                .then((data) => console.log('data', data))

            done();
        });
});

日志显示{ user_id: 4, chat_id: 3 }user_chat表中插入了两次。

预期的结果(以及同步执行时的结果)是一条{ user_id: 2, chat_id: 3 } 记录和一条{ user_id: 4, chat_id: 3 } 记录插入到user_chat 表中。

我无法找到造成这种情况的原因。在我看来,addUserChat 应该插入一条由每次传递的输入生成的记录,无论何时解析。

完整代码库:https://github.com/caseysiebel/lang-exchange

调试控制台输出:https://gist.github.com/caseysiebel/262997efdd6467c72304ee783dadd9af#file-console-L5

【问题讨论】:

    标签: node.js postgresql asynchronous async-await knex.js


    【解决方案1】:

    你需要使用mapSeries 类型机制(这在默认的 Promise API 中不可用)。因此,您可能需要使用其他 3rd 方库,例如 bluebird

    更多详情bluebird mapSeries

    【讨论】:

      猜你喜欢
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多