我有一个API POST路由,我从客户端接收数据并将数据上传到另一个服务。此上传是在post请求(异步)内完成的,需要一段时间。客户端想知道在异步(创建项目功能)完成之前收到了他们的post req。如何在不结束POST的情况下发送? (res.send停止,res.write不会发送出去)
我想在命中此POST路由后立即将http请求发回服务器。 。 。
app.post('/v0/projects', function postProjects(req, res, next) {
console.log('POST notice to me');
// *** HERE, I want to send client message
// This is the async function
createProject(req.body, function (projectResponse) {
projectResponse.on('data', function (data) {
parseString(data.toString('ascii'), function (err, result) {
res.message = result;
});
});
projectResponse.on('end', function () {
if (res.message.error) {
console.log('MY ERROR: ' + JSON.stringify(res.message.error));
next(new Error(res));
} else {
// *** HERE is where they finally receive a message
res.status(200).send(res.message);
}
});
projectResponse.on('error', function (err) {
res.status(500).send(err.message);
});
});
});
内部系统要求在POST请求中调用此createProject函数(需要存在并上传某些内容,否则它不存在) - 否则我将在以后调用它。
谢谢!
答案 0 :(得分:1)
我认为您无法发送post
请求收到的第一个回复,并在内部作业即createProject
已完成时发送另一个回复,无论是成功还是失败。
但可能,您可以尝试:
createProject(payload, callback); // i am async will let you know when done! & it will push payload.jobId in doneJobs
可能性1,如果不需要实际的工作回复:
app.post('/v0/projects', function (req, res, next) {
// call any async job(s) here
createProject(req.body);
res.send('Hey Client! I have received post request, stay tuned!');
next();
});
});
可能性2,如果需要实际的工作响应,请尝试维护队列:
var q = []; // try option 3 if this is not making sense
var jobsDone = []; // this will be updated by `createProject` callback
app.post('/v0/projects', function (req, res, next) {
// call async job and push it to queue
let randomId = randomId(); // generates random but unique id depending on requests received
q.push({jobId: randomId });
req.body.jobId = randomId;
createProject(req.body);
res.send('Hey Client! I have received post request, stay tuned!');
next();
});
});
// hit this api after sometime to know whether job is done or not
app.get('/v0/status/:jobId', function (req, res, next) {
// check if job is done
// based on checks if done then remove from **q** or retry or whatever is needed
let result = jobsDone.indexOf(req.params.jobId) > -1 ? 'Done' : 'Still Processing';
res.send(result);
next();
});
});
可能性3,redis可用于代替可能性2中的内存中队列。
P.S。还有其他选择可以达到预期的效果,但上面提到的是可能的结果。