Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果得到某个结果,重试函数承诺_Javascript_Json - Fatal编程技术网

Javascript 如果得到某个结果,重试函数承诺

Javascript 如果得到某个结果,重试函数承诺,javascript,json,Javascript,Json,我差一点就能让它工作了。此代码查询API以返回reportID,然后使用reportID再次查询以获取数据 function myfunction(ref) { getReport(ref, "queue", "hour", "2018-10-03", "2018-10-04", "pageviews", "page").done(function(r1) { getReport(r1.reportID, "get").done(function(r2) { if (r2

我差一点就能让它工作了。此代码查询API以返回reportID,然后使用reportID再次查询以获取数据

function myfunction(ref) {
  getReport(ref, "queue", "hour", "2018-10-03", "2018-10-04", "pageviews", "page").done(function(r1) {
    getReport(r1.reportID, "get").done(function(r2) {
      if (r2.error == "report_not_ready") {
        console.log("Not ready");
        setTimeout(function() {
          myfunction(ref)
        }, 1000);
      }
      console.log(r2);
    })
  });
}


function getReport(ref, type, granularity, from, to, metric, element) {
  return $.getJSON("report.php", {
    ref: ref,
    type: type,
    granularity: granularity,
    from: from,
    to: to,
    metric: metric,
    element: element,
  });
}
这段代码的问题是,有时当我们尝试获取报告时,报告还没有准备好,所以我们需要稍后重试。如果返回not ready(未准备就绪),则当前的代码将重新运行整个报告,包括生成新的报告ID

它要做的只是重试原始reportID


有人能帮我理解怎么做吗?

下面的代码调用api 3次,然后退出

function reportHandler(id, r2, retries){
    if(retries >= 3){
        console.log("tried 3 times")
        return
    }
    if (r2.error == "report_not_ready") {
        console.log("Not ready");
        setTimeout(function() {
          getReport(id, "get").done(r2=>reportHandler(id, r2, retries + 1))
        }, 1000);
      }
      console.log(r2);
}

function myfunction(ref) {
  getReport(ref, "queue", "hour", "2018-10-03", "2018-10-04", "pageviews", "page").done(function(r1) {
    getReport(r1.reportID, "get").done(r2=>reportHandler(r1.reportID, r2, 0))
  });
}

从代码中,您似乎只需要重新获取
r2
的结果,在这种情况下,我建议您将其提取到自己的方法中,如下所示:

function myfunction(ref) {
    getReport(ref, "queue", "hour", "2018-10-03", "2018-10-04", "pageviews", "page").done(function (r1) {
        getReportFromId(r1.reportID);
    });
}

function getReportFromId(reportId) {
    getReport(reportId, "get").done(function (r2) {
        if (r2.error == "report_not_ready") {
            console.log("Not ready");
            setTimeout(function () {
                getReportFromId(reportId)
            }, 1000);
        }
        console.log(r2);
    })
}

function getReport(ref, type, granularity, from, to, metric, element) {
    return $.getJSON("report.php", {
      ref: ref,
      type: type,
      granularity: granularity,
      from: from,
      to: to,
      metric: metric,
      element: element,
    });
}

这样,您的重试只包括第二次检索。

这是否取决于服务器端脚本的行为?另外,如果报告在您调用时还没有准备好,为什么不让您的XHR等待它完成呢?这就是异步请求的真正意义所在,这样他们就可以在服务器上等待响应,而您的用户不必这样做。除非我误解了你的问题,很可能是这样。@KamilJarosz很可能有更好的方法来做到这一点,但我被告知要使用承诺,这样我就可以在调用准备就绪时将调用中的数据放入另一个函数中。非常想知道您是否有更好的方法。生成报告通常需要多长时间?你能修改它吗?如果它不像一个真正长时间运行的进程,我会将服务器端更改为不返回错误,除非服务器实际无法生成报告。异步请求的性质只是让代码正常继续。您的UI将继续工作,一旦服务器响应,您就可以将报告的值插入到视图中。一个ajax调用,无需重试。出于好奇,你能告诉我们
report.php
在做什么吗?我们可能会提出更好的建议。根据js,如果报告是由服务器生成的,但尚未准备好,则预计会出现错误代码“report\u not\u ready”,这是唯一需要重试的情况,因此我不确定我们还需要知道什么。然后,再次假设“report\u not\u ready”代码在默认情况下不会返回任何错误,这并不是说不能以这种方式完成。我只是说可能有一种更明智的方法,一开始就不需要重试。这段代码工作得很好,唯一的问题是它在三次失败的重试后不会退出代码,但它正确地说“尝试了3次”@Jimmy是的,它应该返回if块,更新代码。