Javascript 重试nodejs http.request(post、put、delete)

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

在nodejs中不使用任何第三方模块的情况下,实现错误/条件重试的正确方法是什么

我不知道如何对错误调用同一个函数,以及如何将原始回调/数据传递给新调用的函数

是否需要销毁/结束插座

我试图寻找示例,但只找到了对第三方模块和http.get示例的引用,这些示例似乎不起作用。如何测试这一点? 我尝试了以下方法,但没有成功:

      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.complete)要做什么还不清楚。由于这是在常规函数回调中,因此
    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);
    })