代码之家  ›  专栏  ›  技术社区  ›  Jimmy

移动返回JSON承诺响应的位置

  •  0
  • Jimmy  · 技术社区  · 7 年前

    这是我的密码:

    function myfunction(ref) {
      getReport(ref, "queue", "hour", "2018-09-03", "2018-10-04", "pageviews", "page").done(function(r1) {
        getReport(r1.reportID, "get").done(r2=>reportHandler(r1.reportID, r2, 0))
        // HERE IS WHERE I WANT TO GET MY DATA RETURNED
          });
    }
    
    
    function reportHandler(id, r2, retries){
        if(retries >= 3){return}
        if (r2.error == "report_not_ready") {
            console.log("Not ready");
            setTimeout(function() {
              getReport(id, "get").done(r2=>reportHandler(id, r2, retries + 1))
            }, 2000);
          }
          // THIS IS NOT WHERE I WANT MY DATA BUT WHERE IT COMES OUT
          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,
      });
    }
    

    这是我能得到的最接近的:

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

    如何将JSON响应的结果从API收集到“myfunction”中,以便在该函数中进行处理。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Tyler Roper    7 年前

    你可以用 async / await 为了这个。

    你可以使用 等待他们的完成。我添加了一个 sleep “等待X毫秒”以替换 setTimeout (通过使用 设置超时 它自己的)。

    const sleep = m => new Promise(r => setTimeout(r, m));
    
    async function myfunction(ref) {
      var r1 = await getReport(ref, "queue", "hour", "2018-09-03", "2018-10-04", "pageviews", "page");
      var r2 = await getReport(r1.reportID, "get").then(r2 => reportHandler(r1.reportID, r2, 0));
      
      console.log(r2);
    }
    
    async function reportHandler(id, r2, retries) {
      if (retries >= 3 || r2.error != "report_not_ready") return r2;
      
      await sleep(2000);                              //Wait 2 seconds
      var report = await getReport(id, "get");        //Try again
      return reportHandler(id, report, retries + 1);  //Until we get a result
    }
    
    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,
      });
    }

    下面是一些调用JSON端点的临时代码,它模拟了几次重试后才得到成功的结果。

    const sleep = m => new Promise(r => setTimeout(r, m));
    
    async function myfunction(ref) {
      var r1 = await getReport();
      var r2 = await getReport().then(r2 => reportHandler(r2, 0));
      console.log(r2);
    }
    
    async function reportHandler(r2, retries) {
      if (retries >= 3) return r2;
      console.log(`Attempt #${retries+1} failed. Retrying in 2 seconds.`);
      
      await sleep(2000);
      var report = await getReport();
      return reportHandler(report, retries + 1);
    }
    
    function getReport() {
      return $.getJSON('https://jsonplaceholder.typicode.com/todos/1');
    }
    
    myfunction();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        2
  •  1
  •   Akrion    7 年前

    你需要向我保证 reportHandler 像这样:

    const myfunction = ref =>
      getReport(ref, "queue", "hour", "2018-09-03", "2018-10-04", "pageviews", "page").then(r1 =>
        getReport(r1.reportId, "get").then(r2 =>
          reportHandler(r1.reportId, r2, 0).then(r3 => {
            console.log(r1,r2,r3);
          })
        );
      );
    
    const reportHandler = (id, r2, retries) =>
        new Promise((resolve, reject) => {
          if(retries >= 3) { resolve() }
          if (r2.error == "report_not_ready") {
            console.log("Not ready");
            setTimeout(function() {
              return getReport(id, "get").then(r2 => reportHandler(id, r2, retries + 1)).then(r => resolve(r))
            }, 2000);
          }
        }
    

    你有 setTimeout 你需要等待。看看这个方法是否适合你。