2017-10-10 20 views
1

私はExpressアプリケーションにかなり簡単なミドルウェア機能を実装しようとしていますが、useCacheという値をメインハンドラに渡されるリクエストオブジェクトに追加するだけですが、何らかの理由でCan't set headers after they were sentエラー。Expressミドルウェアの設定ヘッダーエラー

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ミドルウェアを削除すると、もはやエラーは発生しませんが、エラーの原因となっている機能を特定できません。すべてのポインタが役立ちます!

答えて

1

私は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の状態をチェックしていたことですが、その状態を見つけたら停止するように言われていないので、それを過ぎて続けます。

古いやり方や、あなたの関数を書くための少ない簡潔な方法は次のように次のようになります。そこにelseなければ

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 })) 
    } 
}) 

それがない限り、関数の最後に到達するまで、それは全体の来るif文、それはすべての実行しますあなたはそこで終了するための手がかりとしてreturnキーワードを使用します。

.then()関数内にあるreturn関数を使用すると、約束が解決されることに注意してください。.then()がチェーンされていると、上限スコープから終了しません。

関連する問題