【问题标题】:promises with a recursive call in error Nodejs在错误 Nodejs 中使用递归调用承诺
【发布时间】:2018-12-15 22:25:39
【问题描述】:
requestReport()
.then(getReportData)
.then(checkReportStatus)
.then(handleData)

checkReportStatus = (data) => {
    return new Promise((resolve, reject) => {
        if(data.status === 'completed')
            resolve(data)
        else {
            setTimeout(() => getReportData(), 1000)
        }

所以我先提出报告请求,然后我需要检查报告是否生成(状态将变为已完成)。如果还没有完成,我需要再次调用 getReportData。但我真的对承诺感到困惑。我的代码实际上有很多行,大约有 15 个链接。如果报告未完成,正确的调用方法是什么,以便完成后可以从handleData继续?

edit1:错字

【问题讨论】:

  • = 不是===
  • 这里有2个错误:checkReportStatus(data)之间应该有一个=if(data.status = 'completed')应该是if(data.status == 'completed')
  • 这是我的一个错字,它只是一个伪代码,我更感兴趣的是在 promise 中进行递归调用,直到我得到完成的答案,以便我可以继续进行数据解析。

标签: javascript node.js promise


【解决方案1】:

如果getReportData() 返回一个用数据解析的承诺(它出现在您的.then() 链中)并且不需要来自requestReport() 的任何输入参数,那么您可以这样做:

// utility function that returns a promise that resolves after a delay
// useful for inserting a delay into a promise chain
function delay(t) {
    return new Promise(function(resolve) {
        setTimeout(resolve, t);
    });
}


requestReport()
  .then(getReportData)
  .then(checkReportStatus)
  .then(handleData)

function checkReportStatus(data) {
    if (data.status === 'completed') {
        return data;
    } else {
        // retry after a delay
        // add retry promise to the current promise chain
        return delay(1000).then(getReportData);
    }
}

如果您需要requestReport() 的结果作为getReportData() 的参数,那么您将把该信息传递到承诺链中,以便getReportData() 上的重试可以使用它。您必须向我们展示更多详细信息(从requestReport() 返回哪些数据以及getReportData() 需要哪些数据),以便我们就如何最好地做到这一点提出具体建议。

【讨论】:

  • 这对我来说已经是一个足够好的答案了,谢谢。我的代码真的很乱很长。
【解决方案2】:
checkReportStatus (data) => {
    if (data.status === 'completed') {
        return data;
    } else {
        // retry after a delay
       delay(1000).then(checkReportStatus(data));
    }

}

尝试调用 checkReportStatus(data)。

【讨论】:

  • data 不会随此解决方案而改变,因此在相同数据上再次调用 checkReportStatus(data) 不会完成任何事情。另外,delay() 也没有在您的答案中定义(看来您从我的答案中复制了这个想法,但没有显示实现)。
  • 你真的应该删除你的两个答案,因为没有一个人能回答这个问题,而且你只是在积累反对票(负面声誉),如果你这样做,甚至可能阻止你参与网站的某些部分继续。
猜你喜欢
  • 1970-01-01
  • 2021-11-21
  • 2014-06-14
  • 1970-01-01
  • 2021-06-30
  • 2020-07-22
  • 2020-11-10
  • 2014-02-04
  • 1970-01-01
相关资源
最近更新 更多