【问题标题】:Returning from a express middleware using promise and breaking out from loop returns 404使用 promise 从 express 中间件返回并从循环中中断返回 404
【发布时间】:2020-10-12 08:09:23
【问题描述】:

我正在尝试使用以下与被盗CarDb 对象一起使用的数据库函数从 express 中返回一个对象(汽车)的数组,但数据库函数的功能非常好

执行以下操作会返回 404,错误为 UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

router.post("/reportstolen", function (request: express.Request, response: express.Response, next: (err?: Error) => void) {
    stolenCarDb.put_car(request.body)
        .then(() => {
            stolenCarDb.get_available_cops()
                .then(cops => {
                    cops.forEach(cop => {
                        stolenCarDb.assign_cop_car(cop._id, request.body._id)
                            .then(() => response.status(201).send(`assgined cop ${cop._id} to car`))
                    })
                })
                .then(() => response.status(201).send("created"))
        })
        .catch(() => response.status(500).send("error"))
        .finally(next)
})

【问题讨论】:

    标签: node.js typescript loops express promise


    【解决方案1】:

    您多次向用户发送响应,这是您无法做到的。 在所有操作完成后,您应该只发送一次响应。

    编辑: 如果我必须自己重写代码,我会使用 async/await。你可以阅读更多关于here的信息。

    此外,在重新阅读您的代码时,我看不出在 finally 块中调用 next 的意义。

    异步/等待

    router.post("/reportstolen", async function (request: express.Request, response: express.Response, next: (err?: Error) => void) {
        try {
          await stolenCarDb.put_car(request.body)
          const cops = await stolenCarDb.get_available_cops(); 
          for (const cop of cops) {
            await stolenCarDb.assign_cop_car(cop._id, request.body._id);
          }
    
          response.status(201).send("created")
        } catch (err) {
          response.status(500).send("error")
        }
    });
    

    如果你想显示每个警察到汽车的添加,你可以这样做:

    router.post("/reportstolen", async function (request: express.Request, response: express.Response, next: (err?: Error) => void) {
        try {
          await stolenCarDb.put_car(request.body)
          const cops = await stolenCarDb.get_available_cops();
          for (const cop of cops) {
            await stolenCarDb.assign_cop_car(cop._id, request.body._id);
            res.write(`assgined cop ${cop._id} to car\n`);
          }
    
          response.status(201).send("created")
        } catch (err) {
          response.status(500).send("error")
        }
    });
    

    我还建议您阅读这篇post,了解在循环中使用承诺以及为什么不想在forEach 循环中使用承诺。

    【讨论】:

    • 能否请您重写代码以使其工作?因为我尝试了几次修改,但都没有奏效
    猜你喜欢
    • 1970-01-01
    • 2020-11-28
    • 2016-07-22
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多