每当Node.js中的另一个请求失败时重试一个请求

时间:2018-12-21 15:32:46

标签: node.js request

我正在尝试通过代理进行请求,但是在某些情况下该代理不起作用,因此我必须使用另一个代理。这一切都很酷,但是事情是我正在使用的代理是由同一代码中的先前请求生成的,因此要使用另一个代理,我需要再次请求它,而且自第二次请求以来我不知道该怎么做在第一个请求内(因为否则我无法使用第一个请求返回的结果)。这是我的代码的样子:

function asyncreq(url, proxy) {
  return new Promise(resolve => {
    request({
      url: url,
      proxy: proxy
    }, function(error, response, body) {
      if (typeof response !== 'undefined') {
        if (response.statusCode == 200) {
          resolve(response);
          return;
        }
        resolve(response)
        return;
      }
      resolve(error)
    });
  });
}

asyncreq("http://pubproxy.com/api/proxy?api=" + myapikey + "&type=http&country=fr&format=txt&https=true&post=true").then(function(result) { //FIRST REQUEST
  if (result.statusCode == 200 && result.body.includes("http://") == false) {
    var proxy = result.body;
    console.log("using proxy: " + proxy)
    asyncreq("https://haapi.ankama.com/json/Ankama/v2/Account/CreateGuest?game=20&lang=fr", "http://" + proxy).then(function(result) { //SECOND REQUEST
      if (JSON.parse(result.body).key == undefined) {
        // DO STUFF IF IT IS A SUCESS (If it matters, here i intend to make a third request)
      } else {
        console.log(JSON.parse(result.body).key) //HERE I MUST JUMP TO FIRST REQUEST AGAIN
      }
    })
  } else {
    console.log("Error: " + result.body)
  }
}) 

我试图返回一个失败的值,然后执行while循环,但是它不起作用,因为我不能在函数外使用返回的值

2 个答案:

答案 0 :(得分:0)

在您的承诺中加入rejectreturn new Promise((resolve, reject) => { reject(error) },然后在拒绝您的承诺后再次致电asyncreq

答案 1 :(得分:0)

您可以使用尾递归技术来存档此任务。

在第二个请求之后,您需要选择是重复第一个请求还是继续第三个请求。 多亏了promise链,您可以将promise附加到链及其所有子项(.then)。

此示例应有效:

function asyncreq(url, proxy, validateResponse) {
  return new Promise((resolve, reject) => {
    request({ url, proxy }, function (error, response, body) {
      if (response && validateResponse(response)) {
        resolve(response)
        return;
      }
      reject(response || error)
    });
  });
}

let sharedProxy;    

function firstRequest(myapikey) {
  const firstCallValidation = (response) => {
    return typeof response !== 'undefined' && result.statusCode == 200 && result.body.includes("http://") == false;
  }

  return asyncreq(`http://pubproxy.com/api/proxy?api=${myapikey}&type=http&country=fr&format=txt&https=true&post=true`, null, firstCallValidation)
    .then(function (result) { //FIRST REQUEST
      var proxy = result.body;
      console.log("using proxy: " + proxy)
      sharedProxy = proxy;
      return secondRequest(proxy)
    })
    .then(function (result) { //SECOND REQUEST
      if (JSON.parse(result.body).key == undefined) {
        // DO STUFF IF IT IS A SUCESS (If it matters, here i intend to make a third request)
        return thirdRequest(sharedProxy);
      }
      //HERE I MUST JUMP TO FIRST REQUEST AGAIN
      const apiKey = JSON.parse(result.body).key
      return firstRequest(apiKey)
    });
}

function secondRequest(proxy) {
  return asyncreq("https://haapi.ankama.com/json/Ankama/v2/Account/CreateGuest?game=20&lang=fr", "http://" + proxy, () => true)
}

function thirdRequest(proxy) {
  return asyncreq("https://ha...." + proxy);
}

// Start!!
firstRequest()
  .catch((err) => {
    console.log("Error: ", err)
  })