Javascript 具有多个设置间隔的异步等待

Javascript 具有多个设置间隔的异步等待,javascript,async-await,Javascript,Async Await,我有两个API请求,一个每5000ms调用一次,另一个每30000ms调用一次。我希望确保在向服务器发出新请求之前完成每个调用。我不希望这两个请求彼此重叠。例如,如果func1api尚未完成,则在该调用完成之前,我不想发出func2api调用 这就是我到目前为止所尝试的 async function vals() { try { await func1() .then(response => r

我有两个API请求,一个每5000ms调用一次,另一个每30000ms调用一次。我希望确保在向服务器发出新请求之前完成每个调用。我不希望这两个请求彼此重叠。例如,如果func1api尚未完成,则在该调用完成之前,我不想发出func2api调用

这就是我到目前为止所尝试的

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()。是否应该在vals()函数中设置setInterval?非常感谢您的指导。

好的,这有点棘手!您有两个不同的时间间隔生成任务(http请求),这需要花费大量的时间,并且您希望确保这些任务彼此不一致

我建议不要在超时时立即激活请求,而是将请求添加到要完成的工作队列中。该队列将以最快的速度处理一系列任务

//在您的示例中,“长时间运行的任务”是http请求。
//在本例中,我将使用超时。
让genLongRunningTask1=async()=>{
log(“任务1启动”);
等待新的承诺(r=>setTimeout(r,1500));
console.log(“任务1结束”);
};
让genLongRunningTask2=async()=>{
console.log(“任务2启动”);
等待新的承诺(r=>setTimeout(r,1600));
console.log(“任务2结束”);
};
//承诺队列的尾部。如果问题解决了,我们就准备好了
//开始新的长时间运行任务。它最初已经解决了。
让queueTail=Promise.resolve();
让queueNewTask=async genLongRunningTask=>{
等待队列尾;
等待genLongRunningTask();
};
//现在设置我们的间隔时间。我们不直接产生任何影响
//这里是长时间运行的任务-我们将它们“排队”,然后
//然后将队列的尾部指向它们的完成位置。
log('Starting…');
设置间隔(()=>{
queueTail=queueNewTask(genLongRunningTask1);
}, 3000);
设置间隔(()=>{
queueTail=queueNewTask(genLongRunningTask2);

}, 6000);如何使用
承诺。所有
,当所有作为iterable传递的承诺都已解决时,它将解决问题。如果您的API能够容忍两个请求很少同时发生,那么有一个非常简单的解决方案:确保超时延迟没有小的公共倍数
5000ms
30000ms
循环将每隔
30000ms
一次重合,但
5000ms
29000ms
循环重合的频率要低得多。更好的是,将两个循环的初始化时间偏移2500ms,这样两个循环就永远不会在时间上重合。我更新了我的问题。我需要func1或func2中的每个API调用按顺序运行。Promise.all并行运行所有承诺。在异步函数中通常不使用
then
。您只需等待结果值并使用它们即可。此外,
setInterval
,因此等待结果将立即解决。您考虑过使用自定义事件吗?使用事件的原因是它们的工作方式。如果一个事件处理程序在另一个具有相同签名的事件激发时执行,则第一个事件将始终在执行下一个事件回调之前执行到完成。这是一种简单的方法,可以确保一个任务不会在第一个任务完成之前启动(如果任务、事件处理程序都是相同的)。哎呀,如果其中一个任务的时间超过了它们的时间间隔,你会遇到一个严重的bug
queueTail=…
在分配任务之前不会等待上一个任务。如果您不正确,您可以自己尝试-它实际上可以工作,即使,例如,
genLongRunningTask1
需要
4000ms
才能完成(尽管随着时间的推移,队列将无限增长)。以这种方式重新分配
queueTail
不会破坏队列中已经存在的任何任务。确实,您是对的。似乎
queueNewTask
正在等待
queueTail
,然后才将新任务分配给
queueTail=…
@GershomMaes谢谢您的帮助。任务1需要约2秒才能完成,而任务2需要约7秒。在本例中,我仍然看到新的Task2在最后一个Task1完成之前启动。是否有任何方法可以防止这种情况发生?您可能将其与自己的代码错误地结合在一起!请参阅我的编辑,其中显示了如何使用自己的代码进行此操作的示例。