Получайте вызов каждые 2 секунды, но не хотите, чтобы запросы складывались - PullRequest
1 голос
/ 04 апреля 2019

Я пытаюсь сделать вызов 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, чтобы убедиться, что выборка сработала и завершилась, но не смогла заставить ее работать.

Ответы [ 3 ]

3 голосов
/ 04 апреля 2019

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();

Примечание. При этом учитывается определение плохого случая, запрошенное автором вопроса:

"" плохой случай "(т. Е. Он занимает больше 2 секунд) - я хочу, чтобы он пропустил этот запрос, а затем отправил один новый. Таким образом, в 0 секунд запрос отправляется. Он занимает 3 секунды выполнить, а затем через 2 секунды (в 5) он должен выполнить повторное выполнение. Таким образом, он просто увеличивает время до отправки. "

1 голос
/ 04 апреля 2019

Вы можете добавить finally к вашему try/catch с помощью setTimeout вместо использования вашего setInterval.

Обратите внимание, что такой длинный опрос создает гораздо большую нагрузку на сервер, чем использование веб-сокетов, которые сами по себе гораздо более реалистичны

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()
0 голосов
/ 04 апреля 2019

Simple!Просто сохраните, выполняет ли он в данный момент запрос, и сохраните, не сработал ли таймер, не отправив новый запрос.

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); 
...