The problem is that you never resolve the promise you're waiting on, which is the first promise that looper
returns.
You must always resolve or reject a promise, or make it depend on another one. In this case, the minimal change to do that would be to make the earlier ones depend on the later one by passing the promise from the subsequent looper
into resolve
:
resolve(looper()); // we call the same function again
But that's not what I'd do. Instead, I wouldn't have looper
call itself. I'd have it handle things directly:
function looper() {
function loop(resolve, reject) {
setTimeout(function() {
// if the call is successful
if (x == 5) {
resolve(1); // returns the value 1
} else {
x++; // we increment the value of the counter
console.log("not solved yet");
loop(resolve, reject);
}
}, 5000); // (waits for 5 seconds)
}
return new Promise(loop);
}
As a separate issue, you're not handling failures. It's important to do so. In this case, probably return the promise from looper.then
in the ready
handler and add a catch
:
var x = 1;
$(document).ready(function() {
getJobId(token).then(function(rsp) {
return rsp;
}).then(function(job_id) {
return looper().then(function(rsp) {
console.log("app finished : " + rsp); // this block never gets called
});
}).catch(function(error) {
// Handle/report error here
});
});
function getJobId(token) {
// does an API call that returns a promise
return $.ajax({
url: "url"
});
}
function looper() {
function loop(resolve, reject) {
setTimeout(function() {
// if the call is successful
if (x == 5) {
resolve(1); // returns the value 1
} else {
x++; // we increment the value of the counter
console.log("not solved yet");
loop(resolve, reject);
}
}, 5000); // (waits for 5 seconds)
}
return new Promise(loop);
}
Side note 2: Since you're using Promise
, I take it you're targeting modern environments. That being the case, you might consider using fetch
(which returns a native promise) rather than $.ajax
, which returns a jQuery jqXHR
object which is somewhat Promise-compatible.