如何在javascript/Ajax中添加重试

如何在javascript/Ajax中添加重试,javascript,ajax,Javascript,Ajax,我是javascript和Ajax新手,如果Ajax响应不是200,则需要重试3次 Ajax函数- function fireAndForget(strURL) { log("will try to invoke... [ " + strURL + " ]"); var xmlHttpReq = false; var self = this; // Mozilla/Safari if (window.XMLHttpRequest) { se

我是javascript和Ajax新手,如果Ajax响应不是200,则需要重试3次

Ajax函数-

function fireAndForget(strURL) {
    log("will try to invoke... [ " + strURL + " ]");
    var xmlHttpReq = false;
    var self = this;
    // Mozilla/Safari
    if (window.XMLHttpRequest) {
        self.xmlHttpReq = new XMLHttpRequest();
    } // IE
    else if (window.ActiveXObject) {
        self.xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
    }
    self.xmlHttpReq.open('GET', strURL, true);
    self.xmlHttpReq.onreadystatechange = function() {
        if (self.xmlHttpReq.readyState == 4) {
            if(self.xmlHttpReq.status == 200) {
                log("received JSON response : [" + self.xmlHttpReq.responseText + "]");
                var resObj = parseJSON(self.xmlHttpReq.responseText);
                if("handled" in resObj) {
                    if(resObj.handled) {
                        if("success" in resObj) {
                            if(resObj.success) {
                                // DO NOTHING
                            } else {
                                if(resObj.message) {
                                    alert(resObj.message);
                                }
                            }
                        }
                    }
                } else {
                    log("auth update notification was not handled. response : [" + self.xmlHttpReq.responseText + "]");
                }
            } else {
                // unable to contact the auth update listener
                alert("<%=pNotifyFailedMsg%>");
                log("unable to contact listener URL @ [" + strURL + "]");
            }
        }
    };
    // fire a get request with the SSO information
    self.xmlHttpReq.send(null);
    //alert("sent url : [" + strURL +"]");
}
函数fireAndForget(strURL){
日志(“将尝试调用…[“+strURL+”]”);
var xmlHttpReq=false;
var self=这个;
//Mozilla/Safari
if(window.XMLHttpRequest){
self.xmlHttpReq=新的XMLHttpRequest();
}//即
else if(window.ActiveXObject){
self.xmlHttpReq=新的ActiveXObject(“Msxml2.XMLHTTP”);
}
self.xmlHttpReq.open('GET',strURL,true);
self.xmlHttpReq.onreadystatechange=函数(){
if(self.xmlHttpReq.readyState==4){
if(self.xmlHttpReq.status==200){
日志(“接收到的JSON响应:[“+self.xmlHttpReq.responseText+”]”);
var resObj=parseJSON(self.xmlHttpReq.responseText);
如果(在resObj中处理){
如果(已处理的资源){
如果(“resObj中的成功”){
如果(决议成功){
//无所事事
}否则{
if(resObj.message){
警报(resObj.message);
}
}
}
}
}否则{
日志(“未处理身份验证更新通知。响应:[“+self.xmlHttpReq.responseText+”]”;
}
}否则{
//无法联系身份验证更新侦听器
警报(“”);
日志(“无法联系侦听器URL@[“+strURL+”]”);
}
}
};
//使用SSO信息触发get请求
self.xmlHttpReq.send(null);
//警报(“发送的url:[“+strURL+”]”);
}
需要在上添加重试

if(self.xmlHttpReq.status == 200) {
        log("received JSON response : [" + self.xmlHttpReq.responseText + "]");
        var resObj = parseJSON(self.xmlHttpReq.responseText);
        if("handled" in resObj) {
            if(resObj.handled) {
                if("success" in resObj) {
                    if(resObj.success) {
                        // DO NOTHING
                    } else {
                        if(resObj.message) {
                            alert(resObj.message);
                        }
                    }
                }
            }
        } else {
            log("auth update notification was not handled. response : [" + self.xmlHttpReq.responseText + "]");
        }
    } else {
        // unable to contact the auth update listener
        alert("<%=pNotifyFailedMsg%>");
        log("unable to contact listener URL @ [" + strURL + "]");
    }
if(self.xmlHttpReq.status==200){
日志(“接收到的JSON响应:[“+self.xmlHttpReq.responseText+”]”);
var resObj=parseJSON(self.xmlHttpReq.responseText);
如果(在resObj中处理){
如果(已处理的资源){
如果(“resObj中的成功”){
如果(决议成功){
//无所事事
}否则{
if(resObj.message){
警报(resObj.message);
}
}
}
}
}否则{
日志(“未处理身份验证更新通知。响应:[“+self.xmlHttpReq.responseText+”]”;
}
}否则{
//无法联系身份验证更新侦听器
警报(“”);
日志(“无法联系侦听器URL@[“+strURL+”]”);
}
我在上面代码的其他部分尝试了循环和其他解决方案,但没有成功,请帮助。 在这种情况下,重试的好方法应该是什么


只有在3次重试后才能显示警报(其他部分)

我假设
makeRequest
是所描述的函数,如果您需要经典的JS,您可以将ES6转换为
const x=(a,b=0)=>(c)=>22
函数x(a,b){if(b==undefined){b=0}返回函数(c){…

您的重试生成器函数可能如下所示:

const createRetry = (
  maxRetries, //how many times to try
  passingResults = (id) => id, //function to "pass the result"
  tries = 0, //how many times tried
) => (method, url) =>
  makeRequest(method, url)
    .then(passingResults)
    .catch(
      (error) =>
        tries < maxRetries
          ? createRetry(//call itself again when it failed
              maxRetries,
              tries + 1,//add one to tries as we've just tried
              passingResults,
            )(method, url)
          : Promise.reject(error),//tried max tries times, just reject
    );

const retryTwiceAndNameIsInResponse = createRetry(
  2, //retry twice
  //function to check the xhr json result, if result has a name
  //  property then it passes and just returns the result,
  //  if not then it will reject the promise with an error
  //  a function can be optionally passed, if it's not passed
  //  then it will default to an id function (just returns what it gets)
  (result) =>
    result.name
      ? result
      : Promise.reject(new Error('no name in result')),
  //no need to pass tries in as that defaults to 0 and indicates how
  //  many times the method has tried to get the right result
);

//to use the function:
retryTwiceAndNameIsInResponse(method,url)
.then(response=>console.log('passed, response is:',response))
.catch(error=>console.log('we failed:',error))
const createRetry=(
maxRetries,//要尝试多少次
passingResults=(id)=>id,//用于“传递结果”的函数
尝试次数=0,//尝试了多少次
)=>(方法、url)=>
makeRequest(方法、url)
.然后(passingResults)
.接住(
(错误)=>
尝试<最大重试次数
?createRetry(//失败时再次调用自身
maxRetries,
尝试+1,//添加一个到我们刚刚尝试的尝试中
结果,
)(方法,url)
:Promise.reject(错误),//尝试次数最多,仅拒绝
);
const retryTwiceAndNameIsInResponse=createRetry(
2、//重试两次
//函数检查xhr json结果(如果结果有名称)
//属性,然后它传递并仅返回结果,
//如果没有,那么它将错误地拒绝承诺
//如果未传递函数,则可以选择传递该函数
//然后它将默认为一个id函数(只返回它得到的)
(结果)=>
result.name
?结果
:Promise.reject(新错误(“结果中没有名称”),
//无需传入尝试,因为它默认为0并指示如何传入
//这种方法多次试图得到正确的结果
);
//要使用该功能,请执行以下操作:
retryTwiceAndNameIsInResponse(方法、url)
.then(response=>console.log('passed,response为:',response))
.catch(错误=>console.log('we failed:',error))

这样定义一个函数可能会更简单:
constmakerequest=(maxRetries,tries=0)=>(args)=>xhromise().catch((error)=>tries….catch(error=>)
谢谢,请您详细说明一下我的场景,以获得更多的理解。