问题
I have a hapi.js route where I want to defer the response. I've tried storing the reply function and calling it later, or wrapping it in a promise, but hapi always responds immediately with a 500 Internal Server Error response.
Store the reply for later:
var pendingReplies = {};
server.route({
method: "POST",
path: "/",
handler: function (request, reply) {
var id = generateId();
pendingReplies[id] = reply;
}
});
... // reply later by calling:
function sendResponse(id, data) {
pendingReplies[id](data);
}
I've tried creating a promise to reply:
handler: function (request, reply) {
var id = generateId();
return new Promise(function (resolve, reject) {
pendingReplies[id] = resolve;
}).then(function (data) {
return reply(data);
});
}
I've tried using reply().hold()
handler: function (request, reply) {
var id = generateId();
var response = reply().hold();
pendingReplies[id] = function (data) {
response.source = data;
response.send();
};
return response;
}
I've tried using reply().hold() with a Promise:
handler: function (request, reply) {
var id = generateId();
var response = reply().hold();
return new Promise(function (resolve, reject) {
pendingReplies[id] = resolve;
}).then(function (data) {
response.source = data;
response.send();
return response;
});
}
With each of these, as soon as the handler function exits, I get a 500 response and the following output in the node console:
Debug: internal, implementation, error
Error: Uncaught error: socket hang up
at createHangUpError (_http_client.js:198:15)
at Socket.socketOnEnd (_http_client.js:283:23)
at emitNone (events.js:72:20)
at Socket.emit (events.js:163:7)
at _stream_readable.js:891:16
at process._tickDomainCallback (node.js:388:13)
Is it possible with hapi to reply to a request asynchronously from outside of the route handler?
回答1:
If an error is thrown within your handler, hapi.js will immediately exit and give a 500 status code. Check if generateId() is a valid function.
The rest of your code looks right for your third and fourth examples. reply().hold() is necessary to keep the connection open after handler returns.
回答2:
Since the version 8, Hapi supports Promised responses, so you can do :
var respond = function(message) {
return new Bluebird.Promise(function(resolve, reject) {
setTimeout(() => {
resolve(message);
}, 2000);
});
};
server.route({
method: 'GET',
path: '/',
handler: function (request, reply) {
reply(respond("Hello buddy"));
}
});
来源:https://stackoverflow.com/questions/29402797/how-to-reply-from-outside-of-the-hapi-js-route-handler