等到外部操作完成 setInterval 后再完成

Wait until an external operation completes with setInterval before finishing

我得到了一个简单激活方法的JS代码。此方法调用一个 HTTP 请求,该请求导致某个远程进程开始。然后我需要每 5 秒检查一次远程进程是否以 5 分钟的超时结束,之后我需要停止等待并在超时已过期时抛出错误,否则我需要简单地记录结果并完成方法.

我不确定如何在收到响应之前停止 main 方法的执行,以便我可以记录一个值。这是我到目前为止得到的:

(async function(param) 
{
    ...
    var res = await fetch(...); //activate the remote proccess
    var textAnswer = await res.text();
    var infoObj = JSON.parse(textAnswer);
    startChecks(infoObj.info.id); // this is the method which I need to await on somehow 
}("paramValue");

async function startChecks(id)
{
    var startTime = new Date().getTime();
    intervalId = setInterval(checkStatus, 5000, id, startTime);
    
}

async function checkStatus(id, startTime)
{
  //if more than 5 minutes had passed
  if(new Date().getTime() - startTime > 300000) 
  {
      clearInterval(intervalId);
      throw new Error("External pipeline timeout expired");
  }
  var res = await fetch(...); //check remote process
  var ans = await res.text();
  var obj = JSON.parse(ans);
  if(obj.finished) clearInterval(intervalId);
 }

就像我说的,我想要实现的是我的主要功能不会结束,直到所有时间间隔都完成并且抛出错误或进程完成。我怎样才能做到这一点?

您将创建一个辅助函数,在给定的时间间隔内执行您的函数,直到它解析为与 undefined 不同的值。但仅限于最长时间。

这可能看起来像这样:

// helper to wait for time milliseconds
async function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time));
}

async function repeatedExecution(callback, interval, timeout) {
  // get start time
  const start = Date.now();

  // repeat as long the start time + timout is larger then the current time
  while (start + timeout > Date.now()) {
    // get a promise that resolves in interval seconds
    let sleeper = sleep(interval)

    // execute the callback
    let res
    if (res = await callback()) {
      // if the callback returns something truthy return it
      return res;
    }
    // wait until time for interval ends and then continue the loop
    await sleeper;
  }

  // if we reach this point we timed out
  throw new Error('timed out');
}


async function run() {
  /*
   var res = await fetch(...); //activate the remote proccess
   var textAnswer = await res.text();
   var infoObj = JSON.parse(textAnswer);
  */


  try {
    let result = await repeatedExecution(() => {
      /*
        var res = await fetch(...); //check remote process
        var ans = await res.text();
        var obj = JSON.parse(ans);
      
        if(obj.finished) {
          return true
        }
      */
    }, 1000, 3000);

    // do something on success
  } catch (err) {
    // handle the error (timeout case)
    console.error(err)
  }

}

run();