簡體   English   中英

異步等待多個setIntervals

[英]async await with multiple setIntervals

我有兩個API請求,一個每5000毫秒調用一次,一個每30000毫秒調用一次。 我要確保在向服務器發出新請求之前完成每個調用。 我不希望任何一個請求都相互重疊。 例如,如果func1 API尚未完成,那么在該函數完成之前,我不希望發出func2 API調用。

到目前為止,這是我嘗試過的。

async function vals() {
            try {
                await func1()
                    .then(response => response.json())
                    .then(result => display_result(result))
                    .catch(error => console.error('Error: ', error));
                await func2()
                    .then(response => response.json())
                    .then(result => display_result(result))
                    .catch(error => console.error('Error: ', error));
            }
            catch(error) {
                return error;
            }
}

vals();

這是func1和func2。

function func1() {
        return setInterval(() => fetch(url, { method: 'GET' }), 5000);
}

function func2() {
        return setInterval(() => fetch(url, { method: 'GET' }), 30000);
}

我希望它先運行func1(),等待它解決,然后再運行func2()。 相反,func1()被調用兩次,並且從不訪問func2()。 應該將setIntervals設置在vals()函數內部嗎? 任何指導,使這項工作將不勝感激。

好的,這有點棘手! 您有兩個不同的時間間隔生成任務(http請求),它們花費的時間很短,並且您要確保任務彼此不重合。

我建議不要在超時中立即激活您的請求,而應將請求添加到待完成的工作隊列中。 該隊列將盡可能快地串行處理許多任務。

 // In your example your "long-running-tasks" are http requests. // In this example I'll use a timeout. let genLongRunningTask1 = async () => { console.log('Task 1 start'); await new Promise(r => setTimeout(r, 1500)); console.log('Task 1 end'); }; let genLongRunningTask2 = async () => { console.log('Task 2 start'); await new Promise(r => setTimeout(r, 1600)); console.log('Task 2 end'); }; // The tail of the promise-queue. If it resolves we're ready // to begin a new long-running-task. It's initially resolved. let queueTail = Promise.resolve(); let queueNewTask = async genLongRunningTask => { await queueTail; await genLongRunningTask(); }; // Now setup our intervals. We don't directly generate any // long-running-tasks here - instead we "queue" them, and // then point the tail of the queue to their completion. console.log('Starting...'); setInterval(() => { queueTail = queueNewTask(genLongRunningTask1); }, 3000); setInterval(() => { queueTail = queueNewTask(genLongRunningTask2); }, 6000); 

在我的示例中,兩個間隔分別為3000ms6000ms ,因此它們應該每6000ms同時運行一次-但您會看到排隊邏輯使它們保持良好和獨立狀態! 在上一個任務結束之前,您將永遠不會看到新任務開始。

在您的情況下,您只需要編輯genLongRunningTask1genLongRunningTask2以便它們等待並處理您的請求。 類似於以下內容:

 let genLongRunningTask1 = async () => { try { // Assuming `func1` returns a "response object": let response = await func1(); /* Assuming the "response object" has a `json` method, and `display_result` is an async method for showing the json data. NOTE: this use of `await` ensures requests will remain queued until the previous request is done processing *and* rendering. To begin sending the next request after the previous request has returned, but overlapping with the period in which that request is still *rendering*, omit `async` here. */ await display_result(response.json()); } catch(err) { console.error('Error:', err); } }; 

警告:請注意,排隊任務的速度不會比完成任務的速度快!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM