所以我有我的Express(4.0)配置:
app.get('/api/tracks', (req, res) => {
});
在其中我想查询elasticsearch:
app.get('/api/tracks', (req, res) => {
client.search({
index: 'someindex',
type: 'sometype',
body: {
query: {
match_all: {}
}
}
}, (err, resp) => {
res.json(resp);
});
});
这显然是" async"请求,因为回调情况。
Express如何知道在你发送内容之前一直闲逛,因为在所有的帐户中,response
都可能在搜索完成后发出....(在ES请求之前的方式)完成)
如果Express使用某种类型的事件,那么调用res.end()
之类的东西来表示响应的结束,为什么它不会在所有正常get
&上执行此操作#39; s或post
&#39}并让它们打开?
由于:
app.get('/api/profile', (req, res) => {
res.json({ user: 'callum' });
});
正常工作,根据浏览器response
已完成....
答案 0 :(得分:1)
您只能res.json()
执行一次。考虑这个例子:
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);
使用以下方式访问时:
$ curl http://localhost:3333/json1
你在2秒后得到这个:
{"ok":true}
但是如果您尝试使用以下方式访问它:
curl http://localhost:3333/json2
然后你仍然可以在客户端得到这个:
{"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()
并在获得请求后立即完成请求,但在此之后您无法再次调用它。
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()
两次,第二次通话会被忽略:
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.write()
而不是res.end()
,则请求将等待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);
});
但是消息实际上已经传递 - 您可以通过" \ n"结束消息来观察消息。让curl
在到达时显示它:
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);
});
正如您所看到的,有一些方法可以发送数据 - 比如res.write()
可以多次使用并且不会关闭连接。还有其他方法,如res.json()
,只能使用一次,它们会隐式关闭连接。
但是如果你添加这样的路线:
app.get('/empty', function (req, res) {
});
然后Express会在连接打开的情况下永远等待,因为它无法判断将来是否会调用res.end()
或res.json()
。它只能知道它是否已被调用。