I tried to write a function that requests only limited amount of mock endpoints at one time. As soon as one request is resolved, the next one is fetching.
Here is my code:
const requestQueue = (endpoints, callback, limit = 3) => {
while (endpoints.length > 0) {
if (limit > 0) {
const slice = endpoints.splice(0, limit)
for (const endpoint of slice) {
limit--
fetchMock(endpoint)
.then(data => callback(data))
.catch(err => callback(err))
.finally(() => limit++)
}
}
}
}
function fetchMock(endpoint) {
return Promise.resolve(endpoint)
}
requestQueue([1, 2, 3, 4, 5], data => console.log(data))
It goes in infinite loop and crashes. What am I missing or misunderstaning? Help please.
2
Answers
Use
Promise.all
to run a slice items simultaneously in a batch:Reason for infinite loop is
limit
variable getting decremented to zero inside thefor of
loop; as a result, thewhile
loop’s conditionendpoints.length > 0
is never evaluated asfalse
.The
endpoints.length
is always greater than zero because you don’t let the loop enter theif
block after the first iteration. After the first iteration,limit
is zero, solimit > 0
is nottrue
after the first iteration. As a result, the loop is stuck in an infinite cycle.Now you might say: "But I have increment the
limit
inside thefinally
callback, solimit
is not always zero".For
limit
to get incremented, the callback function offinally
has to be executed BUT that never happens because the asynchronous code (callbacks ofthen
,catch
, andfinally
are invoked asynchronously) is executed after synchronous code execution ends BUT in your case, synchronous code execution never ends because it is stuck in thewhile
loop. You didn’t givefinally
callback a chance to get executed.As a matter of fact, none of the promise callbacks are invoked in your code because synchronous code execution has to end for them to be invoked and you are hoping to end the synchronous code execution after asynchronous callbacks are invoked. Your code is stuck in a deadlock.
Your code can be simplified as below: