Reputation: 989
I want my program to resolve if everything worked and then go onto the next test using a for loop; or, if there is an error, I want it to run again. But if it hits an error six times, I want it to give up and try the next function with the loop.
What I expect:
index is 0 and loop is 0
index is 1 and loop is 0
index is 2 and loop is 0
index is 3 and loop is 0
index is 4 and loop is 0
index is 5 and loop is 0
5 is too many errors
[printed error]
index is 0 and loop is 7
index is 1 and loop is 7
index is 2 and loop is 7
index is 3 and loop is 7
index is 4 and loop is 7
index is 5 and loop is 7
5 is too many errors
[printed error] .. and so on
What I actually get:
index is 0 and loop is 0
index is 1 and loop is 0
index is 2 and loop is 0
index is 3 and loop is 0
index is 4 and loop is 0
index is 5 and loop is 0
5 is too many errors
(node:29808) UnhandledPromiseRejectionWarning: undefined
(node:29808) UnhandledPromiseRejectionWarning: Unhandled promise rejection.
The code:
const hello = async (index, i) => {
return new Promise(async (resolve, reject) => {
console.log(`index is ${index} and loop is ${i}`)
if(index === 5){
reject(console.log(`${index} is too many errors`)) // this runs
} else if (index === 6){
resolve(console.log("I realize it won't ever resolve :) "))
}
else{
hello(++index, i)
}
})
};
const loop_function = async () => {
return new Promise (async(res, rej)=>{
for (var i = 0; i <= 35; i += 7) {
try{
await hello(0, i)
} catch(err){
console.log("caught an error!") // this does not run
}
}
res(console.log("resolved everything")) // this does not run
})
}
const final = async () =>{
await loop_function()
console.log("loop_function complete") // this does not run
}
final();
Upvotes: 0
Views: 47
Reputation: 19288
Things to amend:
new Promise()
wrappers from both functions; they are unnecessary as AsyncFunctions are guaranteed to return Promise and internally you can simply return/throw.return hello(++index, i)
in order to return the outcome of each level of the recursion to its superior levels, and eventually to the original caller at the topmost level.(index >= 5)
condition is met, simply throw an Error; there's no need to log as the caller's (loop_function's) catch
block will do the logging.So, you might end up with :
const hello = async (index, i) => {
console.log(`index is ${index} and loop is ${i}`);
if(index >= 5) {
throw new Error(`${index} is too many errors`);
} else {
return hello(++index, i);
}
};
const loop_function = async () => {
for (var i = 0; i <= 35; i += 7) {
try {
await hello(0, i);
} catch(err) {
console.log(err.message);
}
}
console.log("resolved everything");
}
const final = async () =>{
await loop_function();
console.log("loop_function complete");
}
final();
Upvotes: 3
Reputation: 664548
The problem is that your recursive hello(++index, i)
call is ignored - you never use its result value. It might be a rejected promise (for which you then get the "unhandled rejection" warning), and worse, you never resolve the promise you are constructing. But you should avoid the Promise
constructor antipattern anyway!
async function hello(index, i) {
console.log(`index is ${index} and loop is ${i}`)
if (index === 5) {
throw new Error(`${index} is too many errors`)
} else if (index === 6) {
return "I realize it won't ever resolve :)"
} else {
return hello(++index, i)
// ^^^^^^ this is essential! Or at least `await` the returned promise
}
}
async function loop() {
for (var i = 0; i <= 35; i += 7) {
try {
await hello(0, i)
} catch(err) {
console.log("caught an error!", err)
}
}
console.log("resolved everything")
}
loop().then(() => {
console.log("loop_function complete")
}, () => {
console.log("unhandled error")
})
Upvotes: 1