javascript - Mongoose 难以理解如何正确使用 promises/async await

标签 javascript node.js mongodb

我有一个 nodejs 后端,使用 Mongoose 快速处理我的 API 到我的 mongo 数据库的路由。我更改了代码,使其更易于理解,但本质上我是在构建任务列表。

我有一个用于将任务添加到任务列表的端点,我想维护一个任务列表以便稍后执行一些分析。我遇到的问题是我想检查一个任务是否已经存在,如果该任务不存在,那么我想在我的任务模型中创建它,然后将它添加到我的任务列表中。如果它确实存在,那么我只想将它添加到我的任务列表中。

我的第一个想法是在创建任务时在保存操作上使用异步,因为我想避免嵌套大量的 promise ,因为这会使它变得非常不可读。但是当我的 nodejs 服务器启动时,它给我一个错误 SyntaxError: await is only valid in async function 但是从文档中你可以使用 await on save,并且我的函数有 async 关键字。所以我不知道我做错了什么。

exports.tasklists_add_task = async (req, res, next) => {
    const id = req.params.tasklistId;

    Task.findOne({ externalId: req.body.externalId })
        .exec()
        .then(doc => {

            let task = doc;

            if (!task) {
                task = new Task({
                    _id: new mongoose.Types.ObjectId(),
                    externalId: req.body.externalId,
                    name: req.body.name
                });

                await task.save();
            }
            tasklist.update({_id: id}, {$push: { tasks: tasks }})
            .select("-__v")
            .exec() 
        })
        .then(result => {
            ...
        })
        .catch(err => { ... })
}

我有 2 个模式一个任务模式

const mongoose = require("mongoose");

const taskSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    externalId: { type: String, required: true },
    name: { type: String, required: true }
});

module.exports = mongoose.model("Task", taskSchema);

和一个任务列表模式

const mongoose = require("mongoose");

const taskListSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    user: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true },
    type: { type: String, required: true },
    tasks: [{ type: mongoose.Schema.Types.ObjectId, ref: "Type" }]
});

module.exports = mongoose.model("TaskList", taskListSchema);

我不必在这里使用 async await,我可以只链接 promise ,但我不知道如何以逻辑可读的方式链接 promise ,因为如果任务不存在我必须创建它.

最佳答案

await 只允许在异步函数中使用(前提是您使用的环境支持它)。 Await 仅适用于 async 函数,您的 await 位于非异步的回调内部 - 只有您的顶级函数是 async .你错过了这里的关键字:

.then(doc => {

// Should be:
.then(async doc => {

这样你就可以告诉你的代码 doc 回调是异步函数。但是,由于您的环境中有 async/await,整个 block 可能会重构为看起来像那样!

exports.tasklists_add_task = async (req, res, next) => {
  const id = req.params.tasklistId;

  try {
    let task = await Task.findOne({ externalId: req.body.externalId })
      .exec();

    if (!task) {
       task = new Task({
         _id: new mongoose.Types.ObjectId(),
         externalId: req.body.externalId,
         name: req.body.name
       });

       await task.save();
    }

    const result = await tasklist.update({_id: id}, {$push: { tasks: tasks }}).select("-__v").exec();
  } catch (err) {
    // Error handling here
  } 
}

在大多数情况下,不需要混合使用 async/awaitthen。将其视为处理 promise 并将 then/catch 隐藏在顺序可读代码后面的奇特方式。

我建议调整代码,使其看起来像所提供的解决方案(大量混合 Promises 和 Async/Await 被认为有点反模式)。

关于javascript - Mongoose 难以理解如何正确使用 promises/async await,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52777291/

相关文章:

java - 如何在 HttpSession 中存储 ObjectId 并检索它? (MonoDB Java 驱动程序)

node.js - 缓存来自 MongoDB 的数据

javascript - 一般检查移动设备屏幕方向是否发生变化?

javascript - 是否可以将 contentEditable 与 jQuery DatePicker 一起使用?

javascript - Three.js:使用点从高度图采样

javascript - 使用worker启动Node.js项目

node.js - 更新 Mongoose 中的对象会导致循环

javascript - 如何从 Node.js 中的远程库扩展 `Array.prototype`?

javascript - 如何使用自定义高度图表,如图所示?

mongodb - PyMongo 设置日志级别