表达承诺链如何发送响应并终止承诺链流程?

时间:2018-12-03 23:24:10

标签: javascript node.js express promise

使用下面的代码,我收到此错误:

Unhandled rejection Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client,如果result === null

'use strict'

const HttpStatus = require('http-status-codes')
const { handleErr } = require('ciitizen-express-helpers').utils

function updateOrganization(db, stats) {
  return function (req, res) {
    db.organization.findOne({
      where: {
        id: req.params.id
      }
    })
      .then(result => {

        if (result === null) {
          return res.status(HttpStatus.NOT_FOUND).send() <-- IF RESULT IS NULL, I RETURN THIS 
        }

        console.log('original result = ', result)

        // Update any fields that were passed in
        if (req.body.name) {
          result.name = req.body.name
        }

        if (req.body.address1) {
          result.address1 = req.body.address1
        }

        if (req.body.address2) {
          result.address2 = req.body.address2
        }

        if (req.body.city) {
          result.city = req.body.city
        }

        if (req.body.state) {
          result.state = req.body.state
        }

        if (req.body.zip) {
          result.zip = req.body.zip
        }

        console.log('new result = ', result)
        return result.save()
      })
      .then(result => {
        console.log('final result = ', result)
        return res.status(HttpStatus.CREATED).send(result) <-- BUT IT'S STILL TRYING TO CALL THIS, HENCE THE CAN'T SEND HEADERS ERROR
      })
      .catch(err => {
        req.log.error(err)
        return handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, err.message)
      })
  }
}

module.exports = updateOrganization

在不继续我的承诺链流程的情况下尽早返回响应的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

这样的承诺链

你能做的是

A)return null之后res.status(HttpStatus.NOT_FOUND)(删除该代码之前的return

B)在then(result中检查结果是否为null,如果是,则跳过res.status(...代码

例如

'use strict'

const HttpStatus = require('http-status-codes')
const { handleErr } = require('ciitizen-express-helpers').utils

function updateOrganization(db, stats) {
  return function (req, res) {
    db.organization.findOne({
      where: {
        id: req.params.id
      }
    })
      .then(result => {

        if (result === null) {
          // change A
          res.status(HttpStatus.NOT_FOUND).send();
          return null;
        }
        // snip
        return result.save()
      })
      .then(result => {
        console.log('final result = ', result)
        // change B
        if (result !== null) {
            return res.status(HttpStatus.CREATED).send(result)
        }
      })
      .catch(err => {
        req.log.error(err)
        return handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, err.message)
      })
  }
}

module.exports = updateOrganization

或者,保留现有代码,直到

      .then(result => {
        // change C
        if (!res.headersSent) {
            console.log('final result = ', result)
            return res.status(HttpStatus.CREATED).send(result)
        }
      })

说实话,这可能是“更清洁”的解决方法

答案 1 :(得分:0)

对此进行测试:

tauto