I'm playing around with promises and I'm having trouble with an asynchronous recursive promise.
The scenario is an athlete starts running the 100m, I need to periodically check to see if they have finished and once they have finished, print their time.
Edit to clarify :
In the real world the athlete is running on a server. startRunning
involves making an ajax call to the server. checkIsFinished
also involves making an ajax call to the server. The code below is an attempt to imitate that. The times and distances in the code are hardcoded in an attempt to keep things as simple as possible. Apologies for not being clearer.
End edit
I'd like to be able to write the following
startRunning()
.then(checkIsFinished)
.then(printTime)
.catch(handleError)
where
var intervalID;
var startRunning = function () {
var athlete = {
timeTaken: 0,
distanceTravelled: 0
};
var updateAthlete = function () {
athlete.distanceTravelled += 25;
athlete.timeTaken += 2.5;
console.log("updated athlete", athlete)
}
intervalID = setInterval(updateAthlete, 2500);
return new Promise(function (resolve, reject) {
setTimeout(resolve.bind(null, athlete), 2000);
})
};
var checkIsFinished = function (athlete) {
return new Promise(function (resolve, reject) {
if (athlete.distanceTravelled >= 100) {
clearInterval(intervalID);
console.log("finished");
resolve(athlete);
} else {
console.log("not finished yet, check again in a bit");
setTimeout(checkIsFinished.bind(null, athlete), 1000);
}
});
};
var printTime = function (athlete) {
console.log('printing time', athlete.timeTaken);
};
var handleError = function (e) { console.log(e); };
I can see that the promise that is created the first time checkIsFinished
is never resolved. How can I ensure that that promise is resolved so that printTime
is called?
Instead of
resolve(athlete);
I could do
Promise.resolve(athlete).then(printTime);
But I'd like to avoid that if possible, I'd really like to be able to write
startRunning()
.then(checkIsFinished)
.then(printTime)
.catch(handleError)