Javascript 重试nodejs http.request(post、put、delete)
在nodejs中不使用任何第三方模块的情况下,实现错误/条件重试的正确方法是什么 我不知道如何对错误调用同一个函数,以及如何将原始回调/数据传递给新调用的函数 是否需要销毁/结束插座 我试图寻找示例,但只找到了对第三方模块和http.get示例的引用,这些示例似乎不起作用。如何测试这一点? 我尝试了以下方法,但没有成功:Javascript 重试nodejs http.request(post、put、delete),javascript,node.js,http,Javascript,Node.js,Http,在nodejs中不使用任何第三方模块的情况下,实现错误/条件重试的正确方法是什么 我不知道如何对错误调用同一个函数,以及如何将原始回调/数据传递给新调用的函数 是否需要销毁/结束插座 我试图寻找示例,但只找到了对第三方模块和http.get示例的引用,这些示例似乎不起作用。如何测试这一点? 我尝试了以下方法,但没有成功: async pingApi(cb) { let options = { "method":"post", "pat
async pingApi(cb) {
let options = {
"method":"post",
"path": `/API/pingAPI?${this.auth}`, /ect do I reference this path?
}
};
let request = await http.request(options, (response) => {
let body = new Buffer(0);
response.on('data', (chunk) => {
body = Buffer.concat([body, chunk]);
});
response.on('end', function () {
if (this.complete) {
let decoded = new Buffer(body, 'base64').toString('utf8')
let json = JSON.parse(decoded);
if (json.result != 'OK') {
setTimeout(pingApi, 1000); //cant pass callback
} else {
cb(null, json.result) //works
}
}
});
})
request.end(); //does the socket need to be closed if retry is this function?
}
任何帮助、指出正确的方向或批评都将不胜感激,因为我认为这对我来说是一条非常重要的学习曲线
提前谢谢大家,
我不知道如何对错误调用同一个函数,以及如何将原始回调/数据传递给新调用的函数
我不确定函数中的其他所有内容是否正确,但您可以通过更改以下内容来修复所询问的递归:
setTimeout(pingApi, 1000); //cant pass callback
为此:
setTimeout(() => {
this.pingApi(cb);
}, 1000);
这里没有显示整个上下文,但是如果pingApi()
是一个方法,那么还需要跟踪this
值,以便调用this.pingApi(db)
。您可以使用如下箭头函数回调来保留this
的值:
response.on('end', () => { ... });
我注意到的其他事情如下:
等待http.request()
http.request()
不会返回承诺,因此对其使用wait
不会做任何有用的事情wait
,那么就没有理由将函数声明为async
,因为没有人使用它返回的承诺this
的值不会是您的pingApi对象。您应该使用const self=this
将this
保存在范围的更高位置,或者所有内部回调都需要是箭头函数,以便保留this
的值JSON.parse()周围放置try/catch
,因为如果输入不是完美的JSON,它可能会抛出
下面是代码修复的尝试(未经测试): 然后是示例用法:
pingApi().then(result => {
console.log(result);
}).catch(err => {
console.log(err);
})
您在核心节点服务器上使用async/await引起了我的兴趣,我已经尝试尽可能多地使用这种新的异步特性 这就是我的结局:
const pify=require(“util”).promisify;
const http=require(“http”);
const hostname=“jsonplaceholder.typicode.com”;
const failEndpoint=“/todos/2”;
const goodEndpoint=“/todos/4”;
让选项={
方法:“获取”,
路径:`${failEndpoint}`,
主机名
};
异步函数ping(尝试=0){
返回新承诺((res)=>{
const req=http.request(选项,异步(响应)=>{
让body=新缓冲区(0);
响应.on(“数据”,(块)=>{
body=Buffer.concat([body,chunk]);
})
const on=pify(response.on.bind(response));
等待(“结束”);
let decoded=新缓冲区(主体“base64”)。toString('utf8')
让json=json.parse(解码);
if(json.completed){
归还物(“一切良好”);
}
如果(尝试次数<3){
log(`retrying${trys+1}time`);
返回res(ping(尝试+1));
}
返回res(“失败”);
})
请求开启('错误',(e)=>{
错误(`problemwithrequest:${e.message}`);
});
//将数据写入请求主体
请求结束();
})
}
const status=等待ping();
“状态:”+status
为什么要使用等待http.request()
http.request()
不会返回承诺,因此使用wait
不会做任何有用的事情。而且,使用带有async
函数的回调(根据定义,它返回一个承诺)真的没有意义。对于POST
,您不需要使用request.write()
向请求写入一些正文吗?在发送POST时不发送数据,只发送URL是不常见的。此API需要此函数的POST方法,但不需要除标头以外的任何其他数据。当将数据作为正文的一部分进行post/put时,我确实会将其与此API一起使用。非常感谢:)“这是什么。完成了,它应该引用什么?”根据第3点,我删除了它:有趣的是,通过一点日志记录,它会输出以下内容:pingApi()调用。。。。1调用了pingApi()。。pingApi()调用了。。。。0//no-OKS删除this.complete:OK回调OK回调pingApi()调用..@JohnathanEnslin-我在回答中又添加了一个选项。@jfriend400谢谢。我同意它看起来更干净,尽管它确实有它的缺点,例如依赖NPM和由于所有第三方模块而导致的更大的尺寸。就我而言,我很固执,只使用纯node/javascript进行编程,因为我相信从长远来看,我最终会成为一名更好的开发人员。@JohnathanEnslin-IMO,使用node.js编程的最大优势是所有可用的第三方模块的广度和质量。如果一个已经解决了您需要解决的问题,那么通过键入几个按键,您就可以得到解决您的问题的干净、已经测试和支持的代码。在我看来,这很愚蠢不
const rp = require('request-promise');
const maxRetries = 5;
pingApi(cnt = 0) {
let options = {
method: "post",
url: `http://somedomain.com/API/pingAPI?${this.auth}`,
json: true
};
return rp(options).then(result => {
if (result.result === "OK") {
return result;
} else {
throw "try again"; // advance to .catch handler
}
}).catch(err => {
if (cnt < maxRetries) {
return pingApi(++cnt);
} else {
throw new Error("pingApi failed after maxRetries")
}
});
}
pingApi().then(result => {
console.log(result);
}).catch(err => {
console.log(err);
})