首页 > 解决方案 > 如何重构javascript函数以在不同函数中输出数据

问题描述

我想知道你是否可以帮助我。我有一些有效的代码,我一直在尝试重组。这是它现在的样子:

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))
  });
}

function reportHandler(id, r2, retries){
    if(retries >= 3){
        console.log("Retried 3 times - stopping")
        return
    }
    if (r2.error == "report_not_ready") {
        console.log("Not ready");
        setTimeout(function() {
          getReport(id, "get").done(r2=>reportHandler(id, r2, retries + 1))
        }, 2000);
      }
      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,
  });
}

我一直无法弄清楚的是如何处理数据,我希望能够在 myfunction 中完成。

目前我唯一能做的就是在我的报告处理函数中返回数据。

我希望能够在我的 myfunction 函数中从 API 返回数据,然后我将在其中进一步处理它,然后保持我的 reporthander 和 getreport 函数通用。

标签: javascriptjquery

解决方案


我相信你的问题在这里:

getReport(r1.reportID, "get").done(r2=>reportHandler(r1.reportID, r2, 0))

$.getJSON()作为一个承诺,.done()在功能上与.then(). 这两个都接受一个函数作为参数,但是你传递它的方式不是正确的语法。通过使用参数而不只是其名称来传递函数,您是在告诉 JavaScript 运行该函数并使用它的结果——这不是您想要的。在您的情况下,最简单的解决方法是:

getReport(r1.reportId, "get").done((r2) => { reportHandler(r1.reportId, r2, 0); });

或者,如果您能够使用新的 async/await 语法,则可以使其更简单:

const r2 = await getReport(r1.reportId, "get");
const handler = await reportHandler(r1.reportId, r2, 0);
// and so on

这有意义吗?如果您还有什么不明白的,请告诉我们。

编辑:好的,所以根据对此答案的评论,正在运行的代码的结构正确为:

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);
    });
  });
}

那么,我能想到的唯一答案是,getReport()内部的第一个调用myFunction()没有返回reportId正文中的对象。运行此代码时,您是否遇到任何未捕获的错误?

编辑 2:根据评论,由于大写错误,该属性被错误地引用。r1.reportId响应返回时调用的代码r1.reportID


推荐阅读