异步等待 in() 函数 setInterval()。如何让它变得聪明?
Posted
技术标签:
【中文标题】异步等待 in() 函数 setInterval()。如何让它变得聪明?【英文标题】:asynch await ping() function setInterval(). How to make it smart? 【发布时间】:2022-01-23 10:20:14 【问题描述】:以下代码 ping 我的 nginx 服务器上的 NGINX 位置块,为您提供健康检查状态。
const ping = async () =>
const url = `http://10.10.1.100/status`;
const postData =
method: 'POST', // *GET, POST, PATCH, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
headers:
'Content-Type': 'text/plain; charset=ASCII'
,
body: 'PING'
try
let factor = 1;
let timeout = 3000; // ms
let start = (new Date()).getTime();
const request = await fetch(url, postData);
let delta = new Date().getTime() - start;
delta *= (factor || 1);
if(delta > timeout) throw new Error(`PONG > $timeoutms. Server down?`);
if(!request.ok) throw new Error(`$request.status $request.statusText`);
const response = await request.text();
if(!response) throw new Error(`$response`);
document.getElementById('serverPongSpeed').innerText = `$delta.toFixed(0)ms`;
// Do Something...
console.log(`%c$delta.toFixed(0)ms $response`, "color: #c6ff00"); // Lime A400
catch (error)
console.log(error);
NGINX 位置块:
location = /status
access_log off;
default_type text/plain;
add_header "Access-Control-Allow-Methods" "POST";
add_header "Content-Type" "text/plain";
return 200 "PONG";
现在我是这样运行的:
setInterval(ping, 3000); // Every 3 seconds
问题是,在测试期间,当我关闭 NGINX 以查看 PING 不会中断时会发生什么。它只是不断发送 POST 请求。
也许这是我没有发现的错误?或者可能没有错误,因为 fetch 有更大的超时?也许将获取超时设置为 3 秒会触发一些东西让我抓到..
【问题讨论】:
也许有些东西会缓存您的请求。在您的 Url 请求中添加一些随机字符串结尾。 const url =http://10.10.1.100/status?v=
+(new Date().valueOf());
当你说它“不会中断”时,你的意思是它永远不会捕获 catch
块中的错误吗?
正确。我想在获取失败时至少显示0ms
,因为我故意关闭了 NGINX。但似乎“获取”只是排队,直到我打开 NGINX。在这种情况下,他们从未成功完成。
关机后试试clear interval
。
【参考方案1】:
你可以像这样使用 ClearInterval() 方法:
var interval = setInterval(ping, 3000);
if(timeoutCounter > 3)
clearInterval(interval)
您需要更多代码来计算超时/错误。 类似于断路器模式的东西
【讨论】:
我需要它来保持滴答作响。我想要的是它在 NGINX 关闭时简单地显示0ms
。就像0ms
占位符。
哦!也许不是在!request.ok
时抛出错误,我应该输出0ms
!试试看……
@suchislife 确切地说,你需要把你的逻辑放在 if 语句中而不是抛出异常【参考方案2】:
以下是所需工作解决方案的修订完整示例。
javascript asynch await ping 函数:
-
Ping 函数设置为向 NGINX /status 位置块发送请求。
Ping 功能设置为超时 300 毫秒以指示可能的服务器
下来。
Ping 功能设置为使用预设指示增加的网络延迟
阈值。
Ping 功能设置为捕获网络级别错误和任何其他未知数
错误。
Ping 函数将输出返回到控制台。
...
window.onload = () =>
let precision = 2; // decimals
let pageLoadSpeed = ((window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart) / 1000).toFixed(precision);
document.getElementById('pageLoadSpeed').innerText = `$pageLoadSpeeds`;
console.log(`%cPage loaded in $pageLoadSpeed seconds.`, "color: #c6ff00"); // Lime A400
let polling = null;
// Network latency thresholds
const settings =
pingInterval: 5000, // ms
latency:
factor: 1.0, // Adjust latency to a percentage of its total
high: 99, // ms
moderate: 66, // ms
low: 33, // ms
,
timeout: 300, // ms
consoleLogLimit: 10,
consoleLogCount: 0,
;
const ping = async() =>
const url = `http://10.10.1.100/status`;
const postData =
method: 'POST', // *GET, POST, PATCH, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
headers:
'Content-Type': 'text/plain; charset=ASCII'
,
body: 'PING'
try
const startWatch = (new Date()).getTime();
const request = await fetch(url, postData);
const stopWatch = (new Date().getTime() - startWatch) * (settings.latency.factor || 1);
if (!request.ok) throw new Error(`$request.status $request.statusText`);
const response = await request.text();
if (!response) throw new Error(`$response`);
if (stopWatch >= settings.timeout)
console.log(`%cPONG > $settings.timeoutms. Server down?`, "color: #d500f9"); // purple A400
else if (stopWatch >= settings.latency.high)
console.log(`%c$response: $stopWatchms High Latency`, "color: #ff1744"); // red A400
else if (stopWatch >= settings.latency.moderate)
console.log(`%c$response: $stopWatchms Moderate Latency`, "color: #ffc400"); // amber A400
else if (stopWatch <= settings.latency.low)
console.log(`%c$response: $stopWatchms Low Latency`, "color: #00e676"); // green A400
settings.consoleLogCount++;
// Prevents browser from getting sluggish
if (settings.consoleLogCount == settings.consoleLogLimit + 1)
// Reset count
settings.consoleLogCount = 0;
// Clear console
console.clear();
catch (error)
// Catch network level error
if (error instanceof TypeError && error.message == 'NetworkError when attempting to fetch resource.')
// Clear console
// console.clear();
console.error(`NGINX offline or Network cable unplugged?`);
// Reset count
settings.consoleLogCount = 0;
// Stop polling
clearInterval(polling);
else
// Catch any other error
console.error(error);
polling = setInterval(ping, settings.pingInterval);
...
NGINX 服务器 /status 位置块:
-
端点设置为仅接受
/location
端点上的 POST 请求。
端点访问日志设置为禁用,因为我们真的不需要
记录这个。
端点设置为响应,内容类型设置为 text/plain。
端点设置为接受来自任何来源的 POST 请求。
端点设置为返回 text/plain 的 Content-Type 和文本
成功时“PONG”响应。
...
location = /status
access_log off;
default_type text/plain;
limit_except POST
deny all;
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "POST, OPTIONS" always;
add_header Content-Type "text/plain" always;
return 200 "PONG";
【讨论】:
以上是关于异步等待 in() 函数 setInterval()。如何让它变得聪明?的主要内容,如果未能解决你的问题,请参考以下文章