我有两个API请求,一个每5000毫秒调用一次,一个每30000毫秒调用一次。我要确保在向服务器发出新请求之前完成每个调用。我不希望任何一个请求都相互重叠。例如,如果func1 API尚未完成,那么在该函数完成之前,我不想发出func2 API调用。
这是我到目前为止尝试过的。
DOMPoint
这里是func1和func2。
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()。相反,func1()被调用两次,并且从不访问func2()。应该将setIntervals设置在vals()函数内部吗?任何进行这项工作的指导将不胜感激。
答案 0 :(得分:1)
好吧,这有点棘手!您有两个不同的时间间隔生成任务(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);
在我的示例中,两个间隔分别在3000ms
和6000ms
处,因此它们应在每个6000ms
上同时运行-但您会发现排队逻辑使它们保持良好且独立!在上一个任务结束之前,您将永远不会看到新任务开始。
对于您而言,您只需要编辑genLongRunningTask1
和genLongRunningTask2
,以便它们等待并处理您的请求。类似于以下内容:
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);
}
};
警告:请注意,排队的速度不会比完成任务的速度快!