I work with jQuery and Deferred and there is an (for me) unexpected behavior. I hope you can explain it to me.
What i plan to do is: I want to iterate over a list of keys. For every key I create an deferred and call a function (doSomething), where i pass the key and a callback method (where I resolve the deferred). After the call I add the deferred to a list. The function doSomething does something async and calls at the end the overgiven callback method. After the iteration, I await the deferreds and display some alerts.
The following snippet was my first try, but it isn't working correct. I expected three alerts with '0', '1' and 'first,second'. But I only get '1'.
var doSomething = function(key, callback) {
window.setTimeout(function() {
callback(key);
}, 0)
}
var items = new Array();
var processes = new Array();
var keys = ['first', 'second'];
for (var idx in keys) {
var deferred = $.Deferred();
doSomething(keys[idx], function(item) {
items.push(item);
deferred.resolve();
});
processes.push(deferred.promise());
}
processes[0].done(function() {
alert('0');
})
processes[1].done(function() {
alert('1');
})
$.when.apply($, processes).done(function() {
alert(items);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
The second try was without the async call in doSomething and now I get all three alerts.
var doSomething = function(key, callback) {
callback(key);
}
var items = new Array();
var processes = new Array();
var keys = ['first', 'second'];
for (var idx in keys) {
var deferred = $.Deferred();
doSomething(keys[idx], function(item) {
items.push(item);
deferred.resolve();
});
processes.push(deferred.promise());
}
processes[0].done(function() {
alert('0');
})
processes[1].done(function() {
alert('1');
})
$.when.apply($, processes).done(function() {
alert(items);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
The last try was with an async call in doSomething and do the work in a 'seperate' function called func. This gets me the expected three alerts.
var doSomething = function(key, callback) {
window.setTimeout(function() {
callback(key);
}, 0)
}
var items = new Array();
var processes = new Array();
var keys = ['first', 'second'];
var func = function(key) {
var deferred = $.Deferred();
doSomething(key, function(item) {
items.push(item);
deferred.resolve();
});
return deferred.promise();
}
for (var idx in keys) {
processes.push(func(keys[idx]));
}
processes[0].done(function() {
alert('0');
})
processes[1].done(function() {
alert('1');
})
$.when.apply($, processes).done(function() {
alert(items);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
So my question is: Why does my first try not working like expected? I can't explain why.