使用 express 的异步 CRUD 操作

Asynchronous CRUD operations with express

我有一个使用 html 表单、nodejs/express 和 mongodb 的基本 CRUD 应用程序。我一直在通过回调、承诺和 async/await 学习同步代码和异步代码,根据我对 crud 应用程序的理解,您希望操作是异步的,以便多个用户可以同时执行操作。我正在尝试使用我的快速 crud 操作来实现 aync/await,但不确定它们是同步执行还是异步执行。

这是我的更新功能,它允许用户输入他们想要更改的博客的 _id,然后输入新标题和博客的新 body 并提交。在当前状态下,据我所知它正在同步执行:

app.post('/update', (req, res) => {
    const oldValue = { _id: new mongodb.ObjectId(String(req.body.previousValue)) }
    const newValues = { $set: { blogTitle: req.body.newValue, blogBody: req.body.newValue2 } }
    db.collection("miscData").updateOne(oldValue, newValues, function (err, result) {
        if (err) throw err;
        console.log("1 document updated");
        res.redirect('/')
    });

})

我打算将其更改为异步的方式是这样的:

app.post('/update', async (req, res) => {
    const oldValue = { _id: new mongodb.ObjectId(String(req.body.previousValue)) }
    const newValues = { $set: { blogTitle: req.body.newValue, blogBody: req.body.newValue2 } }
    await db.collection("miscData").updateOne(oldValue, newValues, function (err, result) {
        if (err) throw err;
        console.log("1 document updated");
        res.redirect('/')
    });

})

两个代码块都可以工作,但是我不确定第二个代码块是否在做我打算做的事情,即允许用户在不阻塞调用堆栈的情况下更新博客,或者如果只有在等待之后 运行 更多函数,第二个代码块才有意义。这是否达到了预期目的,如果没有,我是怎么做到的?could/should

db.collection(...).updateOne 总是 异步,因此您不必担心 long-running 数据库操作可能会阻止您的应用程序。有两种方法可以获取异步结果:

带回调函数

db.collection(...).updateOne(oldValues, newValues, function(err, result) {...});
console.log("This happens synchronously");

带有两个参数 (err, result) 的回调函数将在数据库操作完成后(以及 console.log 之后)异步调用。 err 包含数据库错误消息或 result 包含数据库结果。

有承诺

try {
  var result = await db.collection(...).updateOne(oldValues, newValues);
  // Do something with result
} catch(err) {
  // Do something with err
}
console.log("This happens asynchronously");

没有回调函数作为第三个参数的 updateOne 函数 returns 必须 await 的承诺。在数据库操作成功完成后,使用 result 执行某些操作的语句将异步执行。如果发生数据库错误,则执行 catch 块中的语句。在任何一种情况下(成功或错误),console.log 仅在之后执行。

(如果updateOne没有two-parameter版本,可以写

var result = await util.promisify(db.collection(...).updateOne)(oldValues, newValues);

使用 util.promisify。)

您的第二个代码片段包含两种方式的混合(第三个参数加上 await),这没有意义。