UPDATE 2:
Here is a working example using $.Deferred:
<html>
<head>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$.Deferred(function (defer) {
var i;
var duration = 1000;
var pipe = function(defer, index, duration) {
return defer.pipe(function () {
return $(".elem[order='" + index + "']").animate({opacity: 0}, duration);
});
};
defer.resolve();
for (i = 0; i < 5; i++) {
defer = pipe(defer, i, duration);
}
defer.done(function () {
console.log("Done, removing all .elem");
$(".elem").remove();
});
});
});
</script>
<style type="text/css">
body { padding: 20px; }
.elem { border: 1px solid #000; padding: 10px; opacity: 1.0; }
</style>
</head>
<body>
<div class="elem" order="0">elem 0</div>
<div class="elem" order="1">elem 1</div>
<div class="elem" order="2">elem 2</div>
<div class="elem" order="3">elem 3</div>
<div class="elem" order="4">elem 4</div>
</body>
</html>
UPDATE 1, BASED ON NEWLY INTRODUCED DELAY
To answer your comment below, I think your best bet is to simply fire off the callback on the animation that fires last. Since you're in full control of deciding duration (i.e. it's not a randomly generated duration), then you could compute what the last duration will be and use that to decide if it will be the correct iteration in which to fire the callback:
var i, callback, delay;
var onComplete = function () {
console.log("Animations complete!");
};
for (i = 0; i < somevalue; i++) {
delay = i * duration;
callback = delay === ((somevalue - 1) * duration) ? onComplete : $.noop;
//callback = i === somevalue - 1 ? onComplete : $.noop; //this can work too but doesn't check duration
$(".elem[order='" + i + "']").delay(delay).animate({opacity:0}, duration, callback);
}
ORIGINAL ANSWER
It looks like you want all of these elements to start animating at the same time, and have the same duration. Based on this, I would suggest doing a single animate call, and modifying your approach to gathering the collection of elements.
Example:
var i, elements, selector;
for (i = 0; i < somevalue; i++) {
selector = ".elem[order='" + i + "']";
if (i === 0) {
// Start the collection up with the first element
elements = $(selector);
} else {
// Append element to the collection
elements.add(selector);
}
}
// Fire up the animation on all elements
elements.animate({opacity:0}, duration, function () {
console.log("Animation complete!");
});
I haven't actually ran this code, but I'm pretty confident it should work.