Как я уже сказал в своем комментарии, к вашему вопросу у вас был бесконечный цикл, поскольку для вызова nonPromiseCallback
требовался результат tryUntilThree
... и чтобы получить его, tryUntilThree
был вызван ... и это продолжалось до тех пор, пока память не была исчерпана или конец вселенной, в зависимости от того, что наступило раньше.
Вам необходимо внести два изменения:
function nonPromiseCallback(x, resolve, reject){
if(x < 3){
reject(x+1) // the increment of x is moved to here.
}else{
resolve(x)
}
}
function tryUntilThree(x){
return new Promise( (resolve, reject) => {
nonPromiseCallback(x, resolve, tryUntilThree); // Just pass the function, it will be called later
})
}
tryUntilThree(1)
.then(console.log);
Если вы можете использовать async и await (новые функции с 2017 года), вы можете решить это следующим образом (я перенес решение о максимальном количестве попыток в вызывающую функцию):
function nonPromiseCallback(x, resolve, reject){
if(x < 3){
reject(x+1)
}else{
resolve(x)
}
}
async function tryUntilThree(){
const maxAttempts = 3;
let attempt = 1;
do {
try {
// "await" waits for the prommise to resolve or reject.
// If it is rejected, an error will be thrown. That's why
// this part of the code is inside a try/catch-block.
const result = await new Promise( (resolve, reject) =>
nonPromiseCallback( attempt, resolve, reject )
);
return result; // Return the result from nonPromiseCallback
}
catch (error) {
// The nonPromiseCallback failed. Try again
attempt += 1;
}
} while ( attempt <= maxAttempts );
// Signal error after all retires.
throw Error(`Failure, even after ${maxAttempts} tries`);
}
tryUntilThree()
.then(console.log);