ie. ie. - 5 months ago 23
TypeScript Question

Unexpected "then" call order with jQuery promises

I use jQuery promises to track some changes on the server. I also use typescript, so my example is in typescript.

I use the following method for tracking changes:

startObserve(): JQueryPromise<void> {
console.info("initializing...");

const that = this;
let countdown = 3;

return this.loadData()
.then(baseData => {
const checkChanges = () => {
const d = $.Deferred();
d.then(() => {
console.info("checking changes...");

return that.loadData()
.then(data => {
countdown--; // emulate check logic

console.info("next interation! countdown:", countdown);

if (countdown === 0)
return null;

return checkChanges();
});
});
setTimeout(d.resolve, 250);
return d.promise();
};

return checkChanges();
});
}


So I just recursively call
checkChanges
method, which returns new promise until some change detected.

Here is how I try to utilize the
startObserve
method:

this.startObserve()
.then(() => {
console.info("change detected! we can continue!");
}).fail(() => {
console.error("something is very wrong!");
});


I expect to get the following output:

initializing...
checking changes...
next interation! countdown: 2
checking changes...
next interation! countdown: 1
checking changes...
next interation! countdown: 0
**change detected! we can continue!**


But here is what I get:

initializing...
checking changes...
**change detected! we can continue!**
next interation! countdown: 2
checking changes...
next interation! countdown: 1
checking changes...
next interation! countdown: 0


It look a bit strange for me. Where I am wrong? Here is jsfiddle showing the issue: https://jsfiddle.net/4dofznqL/1/

Answer Source

You're returning promise resolved by timeout instead of chaining ajax promise:

...

const checkChanges = () => {
  const d = $.Deferred();
  setTimeout(d.resolve, 250);

  return d.then(() => {
    console.info("checking changes...");

    return that.loadData()
      .then(data => {
      countdown--;

      console.info("next interation! countdown:", countdown);

      if (countdown === 0)
        return null;

      return checkChanges();
    });
  });
};

...