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.