等到外部操作完成 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();
我得到了一个简单激活方法的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();