首页 > 解决方案 > 如何在设定的频率上调用承诺?

问题描述

这是我需要解决的问题。

要检查工单是否完成,我需要定期检查完成状态。

所以每隔几秒或几分钟,我需要再次进行 HTTP 调用以获取工作状态。如果完成了,我就完成了,我会询问结果。如果不完整,我会在下一个时间片再次调用。

我目前所拥有的工作不正常,我已将函数硬编码为始终返回 false,因此我可以看到代码正常工作。

代码如下:

function isBatchRequestCompleted(method: string = 'POST', route: string, batchId: number): boolean {
timerPromise.then(result => {
    CheckESN.sendRequest('POST', 'api/batch/result', batchId)
        .then(result => {
            return false;

        })
        .catch(err => {
            console.error(err);
        });
})
    .catch(err => {
        console.error(err);
    });
return false;

}

const timerPromise = new Promise(function(resolve, reject) {
    setTimeout(() => resolve(() => {
        console.log("timer");
        return 1;
    }), 3000);
});

基本上等待 3s 并检查状态,状态检查总是返回 false

调用代码如下所示:

    do {
             console.log('checking ...')
    }   while  (isBatchRequestCompleted('POST', 'api/batch/submit', +BatchId)  == false);

我看到的是一个“正在检查...”,没有其他 console.logs。

任何人都知道这是不正确的吗?

标签: javascripttypescriptpromise

解决方案


您可以创建一个poll接受 acheckCompletion和函数的resultRequest函数(两者都应该返回一个承诺)。如果checkCompletion用 解析false,则调用该delay()函数,然后poll()再次调用:

const delay = (time) => new Promise(resolve => setTimeout(resolve, time))

const poll = (checkCompletion, resultsRequest) =>     
  checkCompletion() // check for completion
    .then(r => r ?
      resultsRequest() : // if true get the results
      delay(1000).then(() => poll(checkCompletion, resultsRequest)) // if false delay and call poll again
    )

function isBatchRequestCompleted() {
  let i = 0 // used to mock multiple requests
  return poll(
    () => console.log(i) || Promise.resolve(i++ > 3), // the function you use to check completion
    () => Promise.resolve('result') // the function you use to get the results of the job
  );
}

isBatchRequestCompleted().then(console.log)

与 async/await 相同的想法:

const delay = (time) => new Promise(resolve => setTimeout(resolve, time))

const poll = async (checkCompletion, resultsRequest) => {
  let done;
  
  do {
    done = await checkCompletion() // check for completion
  
    if(!done) await delay(1000) // delay if not done
  } while(!done) // continue loop if not done
  
  return resultsRequest() // return the results of calling the request
}

async function isBatchRequestCompleted() {
  let i = 0 // used to mock multiple requests
  return poll(
    () => console.log(i) || Promise.resolve(i++ > 3), // the function you use to check completion
    () => Promise.resolve('result') // the function you use to get the results of the job
  );
}

isBatchRequestCompleted().then(console.log)


推荐阅读