Promise-wrapping http 请求无法结束
Promise-wrapping http request cannot be ended
const http = require("http");
async function sendRequest(url) {
url = new URL(url);
const requestDetails = {
'hostname': url.hostname,
'port': url.port || 80,
'path': url.pathname,
'method': 'GET'
};
const req = await new Promise((resolve, reject) => {
const request = http.request(requestDetails, response => {
const status = response.statusCode;
if (status === 200 || status === 201) {
console.log("SUCCESS");
resolve(request);
} else {
console.log("ERROR");
reject(`Status code returned was ${status}`);
}
});
});
req.end();
}
sendRequest('http://httpbin.org/get');
当 req.end() 在 promise 中时有效,但在传递请求后执行 req.end(),控制台只是保持没有任何响应。我试图通过中间变量比较“req === request”,它返回 true。为什么移出 end() 不起作用?这两个对象不应该一样吗?
您应该将 request.end
调用移到 promise 中,否则它只会调用更新的,因为您将等待更新的 promise 解决,因为请求未发送。
此外,如果请求对象发出错误事件,您应该拒绝承诺。
req.end() 的目的是完成请求。我们可能会小心,如果任何正文部分未发送或可能正在进行中,它将在流中刷新它们,或者如果任何请求被分块,这将发送到终止。
我以稍微不同且更简洁的方式实现了您的相同代码。下面的方法可能有助于为多个 api 重用相同的代码。
const http = require("http");
/**
* @description call the http request
*/
async function doHttp(requestDetails){
return new Promise((resolve, reject)=>{
http.request(requestDetails, response => {
const status = response.statusCode;
response.setEncoding("utf-8");
if (status === 200 || status === 201) {
console.log("SUCCESS");
response.on('data', data => {
return resolve(data);
});
} else {
console.error("ERROR");
return reject(new Error("emptyData"));
}
}).on('error', (err) => {
// Catch the error if occured in request
console.error(`problem with request: ${e.message}`);
return reject(err);
}).end();
});
}
/**
* @description sending the request
*/
async function doSend(url) {
url = new URL(url);
const requestDetails = {
'hostname': url.hostname,
'port': url.port || 80,
'path': url.pathname,
'method': 'GET'
};
const data = await doHttp(requestDetails)
console.log(data);
}
doSend('http://httpbin.org/get');
最后,我们可以说需要 req.end() 才能完成任何请求。这完全取决于我们,我们如何实现一个方法。
另一种解决方案可能是本机 https 模块,例如 Axios、superagent , got, node-fetch.他们在原生 nodejs 代码上提供了一个包装器,可以帮助我们控制处理错误和响应。
const http = require("http");
async function sendRequest(url) {
url = new URL(url);
const requestDetails = {
'hostname': url.hostname,
'port': url.port || 80,
'path': url.pathname,
'method': 'GET'
};
const req = await new Promise((resolve, reject) => {
const request = http.request(requestDetails, response => {
const status = response.statusCode;
if (status === 200 || status === 201) {
console.log("SUCCESS");
resolve(request);
} else {
console.log("ERROR");
reject(`Status code returned was ${status}`);
}
});
});
req.end();
}
sendRequest('http://httpbin.org/get');
当 req.end() 在 promise 中时有效,但在传递请求后执行 req.end(),控制台只是保持没有任何响应。我试图通过中间变量比较“req === request”,它返回 true。为什么移出 end() 不起作用?这两个对象不应该一样吗?
您应该将 request.end
调用移到 promise 中,否则它只会调用更新的,因为您将等待更新的 promise 解决,因为请求未发送。
此外,如果请求对象发出错误事件,您应该拒绝承诺。
req.end() 的目的是完成请求。我们可能会小心,如果任何正文部分未发送或可能正在进行中,它将在流中刷新它们,或者如果任何请求被分块,这将发送到终止。
我以稍微不同且更简洁的方式实现了您的相同代码。下面的方法可能有助于为多个 api 重用相同的代码。
const http = require("http");
/**
* @description call the http request
*/
async function doHttp(requestDetails){
return new Promise((resolve, reject)=>{
http.request(requestDetails, response => {
const status = response.statusCode;
response.setEncoding("utf-8");
if (status === 200 || status === 201) {
console.log("SUCCESS");
response.on('data', data => {
return resolve(data);
});
} else {
console.error("ERROR");
return reject(new Error("emptyData"));
}
}).on('error', (err) => {
// Catch the error if occured in request
console.error(`problem with request: ${e.message}`);
return reject(err);
}).end();
});
}
/**
* @description sending the request
*/
async function doSend(url) {
url = new URL(url);
const requestDetails = {
'hostname': url.hostname,
'port': url.port || 80,
'path': url.pathname,
'method': 'GET'
};
const data = await doHttp(requestDetails)
console.log(data);
}
doSend('http://httpbin.org/get');
最后,我们可以说需要 req.end() 才能完成任何请求。这完全取决于我们,我们如何实现一个方法。
另一种解决方案可能是本机 https 模块,例如 Axios、superagent , got, node-fetch.他们在原生 nodejs 代码上提供了一个包装器,可以帮助我们控制处理错误和响应。