每 2 秒获取一次调用,但不希望请求堆积
Fetch call every 2 seconds, but don't want requests to stack up
我正在尝试拨打 API 电话,我希望它每 2 秒重复一次。但是,我担心如果系统在 2 秒内没有收到请求,它将建立请求并继续尝试发送它们。我该如何防止这种情况?
这是我要执行的操作 fetch
:
const getMachineAction = async () => {
try {
const response = await fetch( 'https://localhost:55620/api/machine/');
if (response.status === 200) {
console.log("Machine successfully found.");
const myJson = await response.json(); //extract JSON from the http response
console.log(myJson);
} else {
console.log("not a 200");
}
} catch (err) {
// catches errors both in fetch and response.json
console.log(err);
}
};
然后我用 setInterval
调用它。
function ping() {
setInterval(
getMachineAction(),
2000
);
}
我曾想过在 setInterval 中做一些类似 promise 的结构,以确保提取已经完成并完成,但无法让它工作。
简单!只存储当前是否正在发出请求,并存储定时器是否已触发而不发送新请求。
let in_progress = false;
let missed_request = false;
const getMachineAction = async () => {
if (in_progress) {
missed_request = true;
return;
}
in_progress = true;
try {
const response = await fetch('https://localhost:55620/api/machine/');
if (missed_request) {
missed_request = false;
setTimeout(getMachineAction, 0);
}
if (response.status === 200) {
console.log("Machine successfully found.");
const myJson = await response.json(); //extract JSON from the http response
console.log(myJson);
} else {
console.log("not a 200");
}
} catch (err) {
// catches errors both in fetch and response.json
console.log(err);
} finally {
in_progress = false;
}
};
要开始间隔,您需要省略 ()
:
setInterval(getMachineAction, 2000);
您可以使用 setTimeout
将 finally
添加到 try/catch
,而不是使用 setInterval
。
请注意,与使用 websockets 相比,像这样的长轮询会产生更多的服务器负载,后者本身更实时
const getMachineAction = async () => {
try {
const response = await fetch( 'https://localhost:55620/api/machine/');
if (response.status === 200) {
console.log("Machine successfully found.");
const myJson = await response.json(); //extract JSON from the http response
console.log(myJson);
} else {
console.log("not a 200");
}
} catch (err) {
// catches errors both in fetch and response.json
console.log(err);
} finally {
// do it again in 2 seconds
setTimeout(getMachineAction , 2000);
}
};
getMachineAction()
The Promise.all() Solution
此解决方案可确保您不会错过 2 秒延迟要求,并且不会在另一个网络呼叫正在进行时触发呼叫。
function callme(){
//This promise will resolve when the network call succeeds
//Feel free to make a REST fetch using promises and assign it to networkPromise
var networkPromise = fetch('https://jsonplaceholder.typicode.com/todos/1');
//This promise will resolve when 2 seconds have passed
var timeOutPromise = new Promise(function(resolve, reject) {
// 2 Second delay
setTimeout(resolve, 2000, 'Timeout Done');
});
Promise.all(
[networkPromise, timeOutPromise]).then(function(values) {
console.log("Atleast 2 secs + TTL (Network/server)");
//Repeat
callme();
});
}
callme();
注意:这会按照问题作者的要求处理不良案例定义:
"the "坏情况”(即需要超过 2 秒的时间)是我希望它跳过该请求,然后发送一个新请求。所以在 0 秒时请求发送。执行需要 3 秒,然后 2 秒后(在 5)它应该重新执行。所以它只是延长了发送时间。“
你可以试试这个,我得到了我正在寻找的确切结果
const getMachineAction = async () => {
try {
const response = await fetch( 'https://localhost:55620/api/machine/');
if (response.status === 200) {
console.log("Machine successfully found.");
const myJson = await response.json(); //extract JSON from the http response
console.log(myJson);
} else {
console.log("not a 200");
}
} catch (err) {
// catches errors both in fetch and response.json
console.log(err);
} finally {
// do it again in 2 seconds
setTimeout(getMachineAction , 2000);
}
};
getMachineAction()
我正在尝试拨打 API 电话,我希望它每 2 秒重复一次。但是,我担心如果系统在 2 秒内没有收到请求,它将建立请求并继续尝试发送它们。我该如何防止这种情况?
这是我要执行的操作 fetch
:
const getMachineAction = async () => {
try {
const response = await fetch( 'https://localhost:55620/api/machine/');
if (response.status === 200) {
console.log("Machine successfully found.");
const myJson = await response.json(); //extract JSON from the http response
console.log(myJson);
} else {
console.log("not a 200");
}
} catch (err) {
// catches errors both in fetch and response.json
console.log(err);
}
};
然后我用 setInterval
调用它。
function ping() {
setInterval(
getMachineAction(),
2000
);
}
我曾想过在 setInterval 中做一些类似 promise 的结构,以确保提取已经完成并完成,但无法让它工作。
简单!只存储当前是否正在发出请求,并存储定时器是否已触发而不发送新请求。
let in_progress = false;
let missed_request = false;
const getMachineAction = async () => {
if (in_progress) {
missed_request = true;
return;
}
in_progress = true;
try {
const response = await fetch('https://localhost:55620/api/machine/');
if (missed_request) {
missed_request = false;
setTimeout(getMachineAction, 0);
}
if (response.status === 200) {
console.log("Machine successfully found.");
const myJson = await response.json(); //extract JSON from the http response
console.log(myJson);
} else {
console.log("not a 200");
}
} catch (err) {
// catches errors both in fetch and response.json
console.log(err);
} finally {
in_progress = false;
}
};
要开始间隔,您需要省略 ()
:
setInterval(getMachineAction, 2000);
您可以使用 setTimeout
将 finally
添加到 try/catch
,而不是使用 setInterval
。
请注意,与使用 websockets 相比,像这样的长轮询会产生更多的服务器负载,后者本身更实时
const getMachineAction = async () => {
try {
const response = await fetch( 'https://localhost:55620/api/machine/');
if (response.status === 200) {
console.log("Machine successfully found.");
const myJson = await response.json(); //extract JSON from the http response
console.log(myJson);
} else {
console.log("not a 200");
}
} catch (err) {
// catches errors both in fetch and response.json
console.log(err);
} finally {
// do it again in 2 seconds
setTimeout(getMachineAction , 2000);
}
};
getMachineAction()
The Promise.all() Solution
此解决方案可确保您不会错过 2 秒延迟要求,并且不会在另一个网络呼叫正在进行时触发呼叫。
function callme(){
//This promise will resolve when the network call succeeds
//Feel free to make a REST fetch using promises and assign it to networkPromise
var networkPromise = fetch('https://jsonplaceholder.typicode.com/todos/1');
//This promise will resolve when 2 seconds have passed
var timeOutPromise = new Promise(function(resolve, reject) {
// 2 Second delay
setTimeout(resolve, 2000, 'Timeout Done');
});
Promise.all(
[networkPromise, timeOutPromise]).then(function(values) {
console.log("Atleast 2 secs + TTL (Network/server)");
//Repeat
callme();
});
}
callme();
注意:这会按照问题作者的要求处理不良案例定义:
"the "坏情况”(即需要超过 2 秒的时间)是我希望它跳过该请求,然后发送一个新请求。所以在 0 秒时请求发送。执行需要 3 秒,然后 2 秒后(在 5)它应该重新执行。所以它只是延长了发送时间。“
你可以试试这个,我得到了我正在寻找的确切结果
const getMachineAction = async () => {
try {
const response = await fetch( 'https://localhost:55620/api/machine/');
if (response.status === 200) {
console.log("Machine successfully found.");
const myJson = await response.json(); //extract JSON from the http response
console.log(myJson);
} else {
console.log("not a 200");
}
} catch (err) {
// catches errors both in fetch and response.json
console.log(err);
} finally {
// do it again in 2 seconds
setTimeout(getMachineAction , 2000);
}
};
getMachineAction()