XMLHttpRequest - 重新发送xhr错误数据

时间:2017-10-27 17:19:40

标签: javascript xmlhttprequest

我在Promise中使用XMLHttpRequest。因为服务器有时是空闲的,所以当出现错误时我想做3次尝试。

但是,如下所示,会在Object state must be opened中的xhr.send()行引发function sendData()错误。为什么?

我认为xhr已经打开了。实现这个目标的正确方法是什么?

function _callService(url, postData) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        var attempts = 0;
        xhr.open("POST", url);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                    resolve(xhr.response);
                }
            }
        };
        xhr.addEventListener("error", onXhrError);

        function sendData() {
           //here I get the Object state must be opened when this is called from onXhrError listener
           xhr.send(postData); 
        };

        function onXhrError() {
            console.log("onXhrError");
            if (attempts < 3) {
                attempts += 1;
                sendData();
            } else {
                reject("OnXhrError")
            }
        };

        sendData();
    });

1 个答案:

答案 0 :(得分:1)

要再次调用_callService(url, postData, attempts)而不是sendData(),请参阅multiple, sequential fetch() Promise

function callService(attempts) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      if (attempts < 3) 
        reject(++attempts)
      else 
        resolve("done");
    }, Math.floor(Math.random() * 1200))
  }).catch(function(err) {
    throw err
  })
}

function request(n) {
  return callService(n)
    .then(function(data) {
      console.log(data);
      return data
    })
    .catch(function(err) {
      console.log(err);
      return typeof err === "number" && err < 3 ? request(err) : typeof err !== "number" ? new Error(err) : "requested " + err + " times";
    })
}

request(0)
  .then(function(done) {
    console.log("done:", done)
  })
  .catch(function(err) {
    console.log(err)
  })