Amy.js
Amy.js

Reputation: 536

Weird variable initialization when using jQuery.when

I find this very counterintuitive:

var bar = 2;
$.when(function(){bar = 1}).then(function(){
  console.log('print ' + bar)
})
// => print 2

It returns 2 in the console instead of 1. But isn't the callback only supposed to be executed once function(){bar=1} is resolved (i.e., bar = 1)? bar was declared as a global variable as well.

Thanks for your help.

Upvotes: 3

Views: 65

Answers (2)

musically_ut
musically_ut

Reputation: 34288

I think this will explain it better:

var bar = 2;
$.when(function(){bar = 1}).then(function(f){
  f(); // The function is 'resolved' and passed to the `then` as the first argument.
       // The execution happens here, when we explicitly call it.
  console.log('print ' + bar)
})
// print 1

Upvotes: 1

Jon
Jon

Reputation: 437376

It's an illusion.

The anon function function(){bar = 1} is not actually executed with this syntax. As per the documentation of $.when, if one of its argument is not a promise then it is treated as a promise that has been resolved with the argument itself as the resolution value.

That is, the code is equivalent to

var f = function(){bar = 1};     // obviously not executed yet
var d = $.Deferred().resolve(f); // still not executed

$.when(d).then(function(){
  console.log('print ' + bar)
})

You can check that this is in fact what happens by making the callback do something visible and having your chained success handler accept an argument:

$.when(function(){alert("invoked!")}).then(function(result){
  result(); // only now is the alert displayed
})

Upvotes: 2

Related Questions