我正在尝试为我的 Express 应用程序实现一个相当简单的中间件函数,该函数只是向传递给主处理程序的请求对象添加一个useCache
值,但由于某种原因,我收到Can't set headers after they were sent
错误。
const cacheControl = (req, res, next) => {
if (lastPulled === null) lastPulled = Date().getDay()
req.useCache = Date().getDay() === lastPulled
next()
}
app.use(cacheControl)
app.get('/missions', (req, res) => {
if (req.useCache) res.status(200).json({ result: cache })
fetch(dumpUrl)
.then(data => data.text())
.then(result => {
cache = result
res.status(200).json({ result })
})
.catch(e => res.status(500).json({ result: e.message }))
})
我已经读到,大多数时候如果错误是由中间件产生的,那是由于多次next()
调用造成的,但这在这里不适用,除非我错过了一些明显的东西。
当我从应用程序中删除cacheControl
中间件时,不再有错误,但我无法弄清楚函数中是什么导致了错误!任何指示都是有帮助的!
我猜这是因为res.json()
发射了两次:
app.get('/missions', (req, res) => {
if (req.useCache) res.status(200).json({ result: cache })
fetch(dumpUrl)
.then(data => data.text())
.then(result => {
cache = result
res.status(200).json({ result })
})
.catch(e => res.status(500).json({ result: e.message }))
})
// if res.useCase is true, set headers and reply
if (req.useCache) res.status(200).json({ result: cache })
// then fetch and reply again (which generates the error)
fetch(dumpUrl)
.then(data => data.text())
.then(result => {
cache = result
res.status(200).json({ result })
将其更改为此以使用显式返回
app.get('/missions', (req, res) => {
if (req.useCache) return res.status(200).json({ result: cache })
return fetch(dumpUrl)
.then(data => data.text())
.then(result => {
cache = result
res.status(200).json({ result })
})
.catch(e => res.status(500).json({ result: e.message }))
})
错误的性质类似于执行此操作时:
问题
function problem() {
if (true === true) console.log('send problem')
console.log('send garbage by accident')
}
console.log(problem())
溶液
function solution() {
if (true === true) return console.log('send solution')
return console.log('send nothing')
}
console.log(solution())
return
是退出函数的方式。您的问题是您的代码正在检查if
条件,但随后继续通过它,因为一旦找到该条件,它就不会被告知停止。
编写函数的旧方法或不太简洁的方式如下:
app.get('/missions', (req, res) => {
if (req.useCache) {
res.status(200).json({ result: cache })
} else {
fetch(dumpUrl)
.then(data => data.text())
.then(result => {
cache = result
res.status(200).json({ result })
})
.catch(e => res.status(500).json({ result: e.message }))
}
})
如果没有else
,它会执行它遇到的每个 if 语句,直到它到达函数的末尾,除非您使用 return
关键字作为退出的提示。
请记住,在 .then()
函数中使用 return
将解决承诺,如果有更多的.then()
链接,它不会退出上限范围。