首页 > 解决方案 > 在 JavaScript 承诺链中实现轮询机制

问题描述

我正在编写一个node.js (v12.13.0)涉及 REST API 的脚本。想象以下任务序列,以相同的顺序执行:

Task 1
 |
User Action
 |
Task 2
 |
Task 3

User Action并且Task 2必须在生成 5 位字母数字代码后的10 分钟Task 1内完成。由于任务 1、2 和 3 在脚本中执行,因此无法准确知道用户何时完成User Action. Task 2因此,唯一的选择是重复调用 REST API,直到生成 OAuth2 授权码。如果 10 分钟过去了,并且 REST API 继续产生错误,那么脚本必须停止,因为它无法执行Task 3

我尝试使用 JavaScript Promise(ES 6)并setInterval按照以下方式实现这一点:

const fnPerformTask1 = () => {
  return new Promise((resolve, reject) => {
    /*
      code goes here, to call REST API and obtain a 5-digit alphanumeric code
     */

    resolve({
      "code": "<5_digit_apha_code>"
      "genTime": new Date()
    })
  });
}

const fnPerformTask2 = (task1Result) => {
  return new Promise((resolve, reject) => {
    /*
      (a) code goes here, to call REST API and obtain an OAuth2 authorization code
      (b) if REST API returns error _and_ 10 minutes have not yet elapsed, repeat step (a)
     */
    resolve(<authorization_code>);
  });
}

const fnPerformTask3 = (task2Result) => {
  return new Promise(resolve, reject) => {
    /*
      code goes here, to call REST API and obtain OAuth2 tokens
     */
    resolve(<tokens>);
  });
}

fnPerformTask1()
  .then(fnPerformTask2)
  .catch(console.error) // if Task 2 fails, break out of this promise chain and don't perform Task 3
  .then(fnPerformTask3)
  .then(console.info)
  .catch(console.error);

我可以在 REST API 返回授权码或 10 分钟后没有收到授权码的情况下实现某种类似轮询的机制吗?可能是因为用户没有Task 2完成10分钟内?PromisesetIntervalUser Action

第二个相关问题是,如果任务 2 无法完成,我该如何打破承诺链?

标签: es6-promise

解决方案


如果任务 2 无法完成,我如何打破承诺链?

fnPerformTask1()
.then(fnPerformTask2)
.catch(err => throw err) // this will break the promise chain and the control will move to subsequent .catch()
.then(fnPerformTask3)
.then(console.info)
.catch((err) => console.log("potential error thrown from fnPerformTask2"));

推荐阅读