javascript - 如何在设定的频率上调用承诺?
问题描述
这是我需要解决的问题。
- 我进行 HTTP 调用以向远程 Web 服务器提交工作订单(请求)。
- 作为回应,我收到了 Guid 回应。
- 此工单将在某个时间点完成,可能需要数小时。
要检查工单是否完成,我需要定期检查完成状态。
所以每隔几秒或几分钟,我需要再次进行 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。
任何人都知道这是不正确的吗?
解决方案
您可以创建一个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)
推荐阅读
- java - 我们可以在 App 模块中使用库模块的资源吗?
- android - 使用 Mp 图表为组条中的每个单独条设置名称
- spacy - 在 spacy 实体链接中显示来自 kb id 的实体描述
- r - 如何在 Mac 上增加 R 的内存限制?
- python - 在递归下传递Python函数内部变量的值
- python - TypeError:传递 PeriodDtype 数据无效。改用`data.to_timestamp()`
- scala - 如何使用主类选择对话框?
- google-apps-script - 从不是由 Google Apps 脚本创建的文件中获取元数据
- c++ - 如何从派生类的构造函数中正确访问这个基类变量?
- android - Android camera2 ImageReader导致冻结