Call an unreliable server, and try again a limited number of times.
What to build
An async function retry(limit), which is the pattern real apps use for flaky networks.
Requirements
- The first input line is the limit: the maximum number of attempts.
- The second line lists what the stand-in server does on each attempt,
okorfail. The starter reads it and providescallServer()for you. - For each failed attempt, print
attempt N: failed. - For a successful attempt, print
attempt N: ok, thenresult: VALUEwith the value the server returned, and stop. - If every attempt fails, print
gave up after L attempts.
Input
Two lines, as described.
Output
As described above.
Constraints
The limit is from 1 to 10. The list always has at least as many entries as the attempts that will be made.
Example
Input:
3
fail ok
Output:
attempt 1: failed
attempt 2: ok
result: data
Why it works
await turns a rejected promise into a thrown error, so an ordinary try and catch can sit inside an ordinary loop. Returning on success ends both the loop and the function at once.
Examples
3 fail ok
attempt 1: failed attempt 2: ok result: data
2 fail fail ok
attempt 1: failed attempt 2: failed gave up after 2 attempts
Hints
Hint 1
Loop from attempt 1 up to the limit, and try callServer inside the loop.
Hint 2
A successful await can return from the function straight away.
Hint 3
If the loop ends, every attempt failed, so report that you gave up.
Solution
Show one correct solution (try it yourself first)
const limit = Number(prompt());
const outcomes = prompt().split(" ");
// A stand-in for a real server: it succeeds or fails as the input says.
function callServer() {
return new Promise((resolve, reject) => {
const outcome = outcomes.shift();
setTimeout(() => (outcome === "ok" ? resolve("data") : reject(new Error("server error"))), 10);
});
}
async function retry(limit) {
for (let attempt = 1; attempt <= limit; attempt++) {
try {
const value = await callServer();
console.log(`attempt ${attempt}: ok`);
console.log(`result: ${value}`);
return;
} catch (err) {
console.log(`attempt ${attempt}: failed`);
}
}
console.log(`gave up after ${limit} attempts`);
}
retry(limit);
Lesson: Asynchronous JavaScript: event loop, promises, async/await →