如何在Node.js中正确取消http请求?
How to cancel http request properly in Node.js?
我需要在 Node.js 中实现可取消的客户端 HTTP 请求,而不使用外部库。我给出了一个 Promise
对象 - cancellationPromise
- 当外部请求取消时它会被拒绝。这就是我知道我可能需要打电话给 request.abort()
的方式。
问题是,只有当 https.request
仍未决并且 response
对象尚不可用时,我才应该调用 request.abort()
吗?
或者,即使我已经获得 response
对象并正在处理响应数据,我是否也应该调用它,如下面的代码所示?在这种情况下,这会阻止更多 response.on('data')
事件的发生吗?
async simpleHttpRequest(url, oauthToken, cancellationPromise) {
let cancelled = null;
let oncancel = null;
cancellationPromise.catch(error => {
cancelled = error; oncancel && oncancel(error) });
try {
const response = await new Promise((resolve, reject) => {
const request = https.request(
url.toString(),
{
method: 'GET',
headers: { 'Authorization': `Bearer ${oauthToken}` }
},
resolve);
oncancel = error => request.abort();
request.on('error', reject);
request.end();
});
if (cancelled) throw cancelled;
// do I need "oncancel = null" here?
// or should I still allow to call request.abort() while fetching the response's data?
// oncancel = null;
try {
// read the response
const chunks = await new Promise((resolve, reject) => {
response.on('error', reject);
const chunks = [];
response.on('data', data => chunks.push(data));
response.on('end', () => resolve(chunks));
});
if (cancelled) throw cancelled;
const data = JSON.parse(chunks.join(''));
return data;
}
finally {
response.resume();
}
}
finally {
oncancel = null;
}
}
这取决于您希望通过中止请求实现什么。
只是一些背景知识。 HTTP 1 无法 "cancel" 它发送请求然后等待响应。您不能 "roll back" 您所做的请求。您需要一个分布式事务来这样做。 (Further reading.) As the MDN developer document states:
The XMLHttpRequest.abort() method aborts the request if it has already been sent. When a request is aborted, its readyState is changed to XMLHttpRequest.UNSENT (0) and the request's status code is set to 0.
基本上,您阻止响应被您的应用程序处理。其他应用程序可能(如果您在发送给它后调用 abort()
)无论如何都会完成处理。
从问题的角度来看:
The question is, should I be calling request.abort()
only if https.request
is still pending and response object is not yet available?
TL.DR.: 仅从您的应用程序的角度来看才重要。当我浏览您的代码时,我认为它可以正常工作。
我需要在 Node.js 中实现可取消的客户端 HTTP 请求,而不使用外部库。我给出了一个 Promise
对象 - cancellationPromise
- 当外部请求取消时它会被拒绝。这就是我知道我可能需要打电话给 request.abort()
的方式。
问题是,只有当 https.request
仍未决并且 response
对象尚不可用时,我才应该调用 request.abort()
吗?
或者,即使我已经获得 response
对象并正在处理响应数据,我是否也应该调用它,如下面的代码所示?在这种情况下,这会阻止更多 response.on('data')
事件的发生吗?
async simpleHttpRequest(url, oauthToken, cancellationPromise) {
let cancelled = null;
let oncancel = null;
cancellationPromise.catch(error => {
cancelled = error; oncancel && oncancel(error) });
try {
const response = await new Promise((resolve, reject) => {
const request = https.request(
url.toString(),
{
method: 'GET',
headers: { 'Authorization': `Bearer ${oauthToken}` }
},
resolve);
oncancel = error => request.abort();
request.on('error', reject);
request.end();
});
if (cancelled) throw cancelled;
// do I need "oncancel = null" here?
// or should I still allow to call request.abort() while fetching the response's data?
// oncancel = null;
try {
// read the response
const chunks = await new Promise((resolve, reject) => {
response.on('error', reject);
const chunks = [];
response.on('data', data => chunks.push(data));
response.on('end', () => resolve(chunks));
});
if (cancelled) throw cancelled;
const data = JSON.parse(chunks.join(''));
return data;
}
finally {
response.resume();
}
}
finally {
oncancel = null;
}
}
这取决于您希望通过中止请求实现什么。
只是一些背景知识。 HTTP 1 无法 "cancel" 它发送请求然后等待响应。您不能 "roll back" 您所做的请求。您需要一个分布式事务来这样做。 (Further reading.) As the MDN developer document states:
The XMLHttpRequest.abort() method aborts the request if it has already been sent. When a request is aborted, its readyState is changed to XMLHttpRequest.UNSENT (0) and the request's status code is set to 0.
基本上,您阻止响应被您的应用程序处理。其他应用程序可能(如果您在发送给它后调用 abort()
)无论如何都会完成处理。
从问题的角度来看:
The question is, should I be calling
request.abort()
only ifhttps.request
is still pending and response object is not yet available?
TL.DR.: 仅从您的应用程序的角度来看才重要。当我浏览您的代码时,我认为它可以正常工作。