【发布时间】: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) => {内部,未标记为async。我建议你在Todo.findByPk上使用async/await,这样你就不会遇到嵌套函数调用(使用.then()或await,尽量不要混合使用)
标签: javascript node.js asynchronous module