2016-09-25 3 views
0

だから私は持っている私のエクスプレス(4.0)の設定:私はelasticsearch照会することで非同期エクスプレスミドルウェアは、どのようにそれは知っているん

app.get('/api/tracks', (req, res) => { 

}); 

app.get('/api/tracks', (req, res) => { 
    client.search({ 
     index: 'someindex', 
     type: 'sometype', 
     body: { 
      query: { 
       match_all: {} 
      } 
     } 
    }, (err, resp) => { 
     res.json(resp); 
    }); 
}); 

これは明らかに「非同期」でありますコールバック状況のために要求します。

すべてのアカウントで、responseは、検索が実行を終了したときに送出されている可能性があるため、どのようにExpressは、あなたが何かを送信するまでたむろして知っているん....(ES要求が完成していたの前に道)

Expressは何らかのイベント使用のようなものを利用しているので、res.end()のようなものを呼び出して応答の終わりを知らせますが、それは普通のgetのものかpostのものであり、

ので:

app.get('/api/profile', (req, res) => { 
    res.json({ user: 'callum' }); 
}); 

は、ブラウザが終了しているに応じて正常動作し、response ....

答えて

1

あなたは一度だけres.json()を行うことができます。

$ curl http://localhost:3333/json1 

あなたは2秒後にこれを取得する:あなたがそれにアクセスすると

var express = require('express'); 
var app = express(); 

app.get('/json1', function (req, res) { 
    setTimeout(function() { 
    res.json({ok:true}); 
    }, 2000); 
}); 

app.get('/json2', function (req, res) { 
    setTimeout(function() { 
    res.json({ok:true}); 
    res.json({ok:true}); 
    }, 2000); 
}); 

app.listen(3333); 

:この例を考えてみましょう

{"ok":true} 

をしかし、あなたがそれにアクセスしよう

curl http://localhost:3333/json2 

あなたはまだあなたのc lient側:と

{"ok":true} 

しかし、あなたのサーバーがクラッシュ:

_http_outgoing.js:344 
    throw new Error('Can\'t set headers after they are sent.'); 
    ^

Error: Can't set headers after they are sent. 
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11) 

これは、Expressがres.json()を待ち、とすぐにそれが1を取得するよう要求を終了しますが、その時点の後、あなたはそれを呼び出すことができないことを意味2回目。

res.send()と同じことが起こります。一方

app.get('/send1', function (req, res) { 
    setTimeout(function() { 
    res.send('ok'); 
    }, 2000); 
}); 

app.get('/send2', function (req, res) { 
    setTimeout(function() { 
    res.send('ok'); 
    res.send('ok'); 
    }, 2000); 
}); 

、あなたが二回res.end()を呼び出すことができますし、2番目の呼び出しは無視されることを思わ::それらのルートを参照してください

app.get('/end1', function (req, res) { 
    setTimeout(function() { 
    res.end('ok'); 
    }, 2000); 
}); 

app.get('/end2', function (req, res) { 
    setTimeout(function() { 
    res.end('ok'); 
    res.end('ok'); 
    }, 2000); 
}); 

しかし、あなたは、代わりにres.end()の要求をres.write()を使用している場合だろうres.end()を待って、決して仕上げ:

app.get('/end1', function (req, res) { 
    setTimeout(function() { 
    res.end('ok'); 
    }, 2000); 
}); 

app.get('/end2', function (req, res) { 
    setTimeout(function() { 
    res.end('ok'); 
    res.end('ok'); 
    }, 2000); 
}); 

しかし、メッセージ、実際に配信されます - Y - 何度も使用することができますres.write()よう

app.get('/write1', function (req, res) { 
    setTimeout(function() { 
    res.write('ok\n'); 
    }, 2000); 
}); 

app.get('/write2', function (req, res) { 
    setTimeout(function() { 
    res.write('ok\n'); 
    res.write('ok\n'); 
    }, 2000); 
}); 

をあなたが見ることができるように、データを送信するために特定の方法があります。ouはそれが到着したときにcurlがそれを表示するために「\ nの」によってメッセージを終了することで観察することができます接続を閉じることはありません。 res.json()のように、一度だけ使用でき、暗黙的に接続を閉じるなどの方法があります。

しかし、あなたはこのようなルートを追加した場合:

app.get('/empty', function (req, res) { 
}); 

を、それがres.end()またはres.json()は、将来的に呼び出されるかどうかを指示する方法がないので、次にExpressは、オープン接続を永遠に待ちます。すでに呼び出されているかどうかだけを知ることができます。

+0

基本的に、 'send'や' json'が 'response'に何か書き込まれるか、タイムアウトするまで、接続は開いたままです。 –

+0

@ CallallLiningtonはい。しかし、(Express側の)タイムアウトのためには、 'connect-timeout'のようなミドルウェアを' var timeout = require( 'connect-timeout')で使う必要があります。 app.use(timeout( '5s')); 'などのようなものです。それ以外の場合、Expressはおそらくクライアント側のタイムアウトまたはTCP接続のタイムアウトを待機します。 – rsp

+0

ああ、それは宝石です! –

関連する問題