(jQuery 1.7.2 を対象としています。1.8pre では then() が pipe() と同じものになっているので、かわりに then() を使っても動くようです。)
対象の要素が同じであれば、以下のように animate() を連続して呼ぶと queue にアニメーションが溜まり、順番に実行されます。
$elem1.animate({left: 500}, 1000)
.animate({top: 300}, 1000)
.animate({left: 0}, 1000);
ところが queue は要素ごとであるため、対象の要素が違う場合は同じようにはいきません。そこで $.Deferred を使うことで同様のことが実現できます。
$.Deferred(function(dfd) {
dfd.pipe(function() { return $elem1.animate({left: 500}, 1000); })
.pipe(function() { return $elem2.animate({top: 300}, 1000); })
.pipe(function() { return $elem1.animate({left: 0}, 1000); });
}).resolve();
pipe() は、引数の関数の戻り値が observable である、つまり promise() という関数プロパティを持っていると、その戻り値の Promise を使って待ってくれます。animate() は jQuery オブジェクトを返しますが、jQuery オブジェクトの promise() は、要素のアニメーションが全て終わった時に resolve される Promise を返します。このため、アニメーションが順番に実行されるのです。
詳しくは以下を参照。