每 2 秒获取一次调用,但不希望请求堆积起来

tha*_*ker 2 javascript asynchronous fetch promise

我正在尝试进行 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);
    }
};
Run Code Online (Sandbox Code Playgroud)

然后我用setInterval.

function ping() {
    setInterval(
        getMachineAction(),
        2000
    );        
}
Run Code Online (Sandbox Code Playgroud)

我曾想过在 setInterval 中做一些类似结构的承诺,以确保获取已经工作并完成,但无法让它工作。

cha*_*tfl 6

您可以使用 a 添加 a到finally您的,而不是使用您的.try/catchsetTimeoutsetInterval

请注意,像这样的长轮询会比使用 websocket 产生更多的服务器负载,而 websocket 本身更加实时

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()
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这会在请求完成后 2000 秒发生,而不是在请求开始后 2000 秒发生。 (2认同)

tak*_*hna 5

所述Promise.all()解决方案

此解决方案可确保您不会错过 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();
Run Code Online (Sandbox Code Playgroud)

注意:这会按照问题作者的要求处理坏情况定义:

“坏情况”(即它需要超过 2 秒的时间)是我希望它跳过该请求,然后发送一个新的请求。所以在 0 秒时发送请求。执行需要 3 秒,然后是 2 秒稍后(在 5 点)它应该重新执行。所以它只是延长时间直到它发送。”