【问题标题】:why is a function with async modifier throwing error on await call为什么带有异步修饰符的函数在等待调用时抛出错误
【发布时间】:2022-01-28 18:48:23
【问题描述】:

我有一个 node+ express 应用程序,其中控制器方法正在执行异步操作。即使使用 async 修饰符声明该方法,它也会抛出 SyntaxError: await is only valid in async functions and the top level bodies of modules

路线设置如下:

var express = require("express");
var router = express.Router();

//create  and  import controllers
var todoCtr = require("../controllers/todos");

router.get("/todos", todoCtr.listTodos);
router.post("/todos", todoCtr.createTodo);
router.put("/todos/:todoId", todoCtr.updateTodo);

module.exports = router;

我的 todo 控制器文件夹的结构是每个方法都有自己的文件,然后在index.js 文件中作为一个整体导出。

index.js 文件: index.js

const createTodo = require("./createTodo");
const listTodos = require("./listTodos");
const updateTodo = require("./updateTodo");

module.exports = {
  listTodos,
  createTodo,
  updateTodo,
};

更新方法如下所示: updateTodo.js

const Todo = require("../../models").Todo;
const Subtask = require("../../models").Subtask;
const { isStatusChangeCorrect } = require("./helpers/updateTodoHelpers");
const { Op } = require("sequelize");

module.exports = async (req, res) => {
  //find the todo needed to be updated
  return Todo.findByPk(req.params.todoId)
    .then((todo) => {
      if (!todo) {
        return res.status(404).send({
          message: "Todo Not Found",
        });
      }
       const  answerr = await isStatusChangeCorrect(todo.status, req.body.status, req.params.todoId);

      console.log("aaa2", subtaskMarkedCompleted);
      console.log("aaa", totalSubtasks);
      return todo
        .update({
          status: req.body.status || todo.status,
        })
        .then(() => res.status(200).send(todo))
        .catch((error) => res.status(400).send(error));
    })
    .catch((error) => res.status(400).send(error));
};

在这里,我尝试将 await 用于执行 db/asynchorous 操作的函数 (isStatusChangeCorrect),但我收到一条带有跟踪堆栈的错误消息:

/Users/haroonAzhar/Desktop/test/OOZOU-TEST/server/controllers/todos/updateTodo.js:15
       const  answerr = await isStatusChangeCorrect(todo.status, req.body.status, req.params.todoId);
                        ^^^^^

SyntaxError: await is only valid in async functions and the top level bodies of modules
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1026:15)
    at Module._compile (node:internal/modules/cjs/loader:1061:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:999:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/Users/haroonAzhar/Desktop/test/OOZOU-TEST/server/controllers/todos/index.js:3:20)
    at Module._compile (node:internal/modules/cjs/loader:1097:14)  

当函数使用async modifier 声明时,为什么会出现语法错误?

助手还没有完成,但看起来像这样:todoHelpers/updateTodoHelper.js

const Todo = require("../../models").Todo;
const Subtask = require("../../models").Subtask;
const isStatusChangeCorrect = async (currrentStatus, statusToSet, todoId) => {
  let totalSubtasks;
  let subtaskMarkedCompleted;
  const countPromise = Subtask.findAndCountAll({
    where: {
      parentId: req.params.todoId,
    },
  });
  // .then((result) => {
  //   totalSubtasks = result.count;
  //   console.log("ez  ccount 1", result.count);
  // });
  const countPromise2 = Subtask.findAndCountAll({
    where: {
      [Op.and]: [{ parentId: req.params.todoId }, { status: "completed" }],
    },
  });
  Promise.all(
    [countPromise, countPromise2].map((e) => e.catch((error) => console.log(e)))
  ).then((values) => {
    if (values[0].count !== values[1].count)
      return res
        .status(400)
        .send(
          "can't change state to completedd when all subtaks are not compleed  "
        );
  });
};

module.exports = {
  isStatusChangeCorrect,
};

【问题讨论】:

  • await isStatusChangeCorrect.then((todo) =&gt; { 内部,未标记为async。我建议你在Todo.findByPk 上使用async/await,这样你就不会遇到嵌套函数调用(使用.then()await,尽量不要混合使用)

标签: javascript node.js asynchronous module


【解决方案1】:
module.exports = async (req, res) => {
   //find the todo needed to be updated
   return Todo.findByPk(req.params.todoId)
     .then(async (todo) => { // add async right here
        if (!todo) {
          return res.status(404).send({
          message: "Todo Not Found",
        });
     }
     const  answerr = await isStatusChangeCorrect(todo.status, req.body.status, 
  req.params.todoId);

  console.log("aaa2", subtaskMarkedCompleted);
  console.log("aaa", totalSubtasks);
  return todo
    .update({
      status: req.body.status || todo.status,
    })
    .then(() => res.status(200).send(todo))
    .catch((error) => res.status(400).send(error));
   })
    .catch((error) => res.status(400).send(error));
 };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-16
    • 2020-03-16
    • 1970-01-01
    • 2020-08-22
    • 2014-08-17
    • 2021-11-18
    • 1970-01-01
    • 2019-08-19
    相关资源
    最近更新 更多