当我在我创建的函数中遇到错误时如何退出整个 try 块

How to exit the whole try block when I encounter an error inside a function that I created

try {
    const skills = []
    
    req.body.skills.forEach(async (element) => {
        const skill = await Skill.findOne({name : element.skill})

        if (!skill) {
            return res.status(400).send('Skill : '+element.skill+' is not present')
        }

        skills.push(
            {
                skill : skill._id,
                skillname : skill.name
            }
        )
    })

    if (!await User.findOne(req.params)) {
        return res.status(400).send('The username : '+req.params.username+' doesnot exist')
    }

    console.log(skills);

    res.status(200).send(req.body)

} catch (error) {
    console.log(error);
}

在此我遇到错误,当数据库中不存在该技能时,如:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:526:11)
at ServerResponse.header (D:\Teamin\teaminbackend\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (D:\Teamin\teaminbackend\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (D:\Teamin\teaminbackend\node_modules\express\lib\response.js:267:15)
at ServerResponse.send (D:\Teamin\teaminbackend\node_modules\express\lib\response.js:158:21)
at D:\Teamin\teaminbackend\router\user.js:48:25
at processTicksAndRejections (internal/process/task_queues.js:97:5) {

代码:'ERR_HTTP_HEADERS_SENT' }

所以我想知道当我在我创建的函数中遇到错误时如何退出整个 try 块(return 语句只跳出我创建的函数而不是整个 try 块因此它尝试 运行 代码

res.send(req.body)

导致错误

尝试这样的事情:

try {
    const skills = []
    
    req.body.skills.forEach(async (element) => {
        const skill = await Skill.findOne({name : element.skill})

        if (!skill) {
            throw { status: 400, message: 'Skill :'+element.skill+'is not present' };
        }

        skills.push(
            {
                skill : skill._id,
                skillname : skill.name
            }
        )
    })

    if (!await User.findOne(req.params)) {
        throw { status: 400, message: 'The username : '+req.params.username+' doesnot exist' };
    }

    console.log(skills);

    res.status(200).send(req.body)

} catch (error) {
    console.log(error);
    return res.status(error.status).send(error.message);
}

如您在 Array.prototype.forEach() 的 MDN 文档中所见:

Note: There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool.

Early termination may be accomplished with:

  • A simple for loop
  • A for...of / for...in loops Array.prototype.every()
  • Array.prototype.some()
  • Array.prototype.find()
  • Array.prototype.findIndex()

Array methods: every(), some(), find(), and findIndex() test the array elements with a predicate returning a truthy value to determine if further iteration is required.

因此您需要使用 for 循环来控制流程而不是 Array.prototype.forEach():

try {
    const skills = []
    
    for (const element of req.body.skills) {
    
        const skill = await Skill.findOne({name : element.skill})

        if (!skill) {
            return res.status(400).send('Skill : '+element.skill+' is not present')
        }

        skills.push(
            {
                skill : skill._id,
                skillname : skill.name
            }
        )
    }

    if (!await User.findOne(req.params)) {
        return res.status(400).send('The username : '+req.params.username+' doesnot exist')
    }

    console.log(skills);

    res.status(200).send(req.body)

} catch (error) {
    console.log(error);
}

这样,return 语句使周围的函数成为 return(而不是 Array.prototype.forEach() 完全无效的回调)。