2016-11-11 10 views
0

このフィドルはjqueryの遅延オブジェクトに関するものです。実行順序は1,4,2,3です。 jquery v1.xとでは期待通りに動作しますが、v3.xでは動作しません。私は何が欠けていますか?jQuery deferredはjQuery v1.xとv2.xで動作しますが、v3.xでは動作しません

適切な順序は1,4,2,3,all doneですがv3で、それは単純にjQueryのバージョンを変更し、あなたがv3.xと、それは1,4,2,3ために動作しないことがわかりますwhen/all doneトリガ3

前に意味をなさない1,2,4,all done,3です。

フィドル

https://jsfiddle.net/ergec/mrd2dt3a/

、これらはコードです。

CSS

div { 
    width: 0px; 
    height: 20px; 
} 

.div1 { 
    background-color: red; 
} 

.div2 { 
    background-color: yellow; 
} 

.div3 { 
    background-color: lightblue; 
} 

.div4 { 
    background-color: gray; 
} 

ジャバスクリプト

var defer = $.Deferred(); 
var div1 = defer.then(function(value) { 
    return $(".div1").animate({ 
     width: "100%" 
    }, 1000); 
}); 
var div2 = div1.then(function(value) { 
    $("#status").append("<p>div1 done</p>"); 
    return $(".div2").animate({ 
     width: "100%" 
    }, 3000); 
}); 
var div3 = div2.then(function(value) { 
    $("#status").append("<p>div2 done</p>"); 
    return $(".div3").animate({ 
     width: "100%" 
    }, 2000, function() {$("#status").append("<p>div3 done</p>");}); 
}); 
var div4 = function() { 
    return $.Deferred(function(dfd) { 
     $(".div4").animate({ 
     width: "100%" 
     }, 1500, dfd.resolve); 
    }).promise().done(function() {$("#status").append("<p>div4 done</p>");}); 
} 
$.when(div1, div2, div3, div4()).then(function() { 
    $("#status").append("<p>all done</p>"); 
}); 
defer.resolve(); 

HTML

<div class="div1">div1</div> 
<div class="div2">div2</div> 
<div class="div3">div3</div> 
<div class="div4">div4</div> 
<span id="status"></span> 
+0

それは正常に動作します。おそらく、間違ったバージョンの3.xを含んでいるでしょう(スリムバージョンはすべてのメソッドを持っていません)。 –

+1

@KevinB順序は異なります。それは '1,4,2,3、すべて完了'でなければなりません。しかし、 'v3'では' 1,2,4、all done、3'が '3 /' done 'の前にトリガするのを意味しません。すべて完了した後に最後にする必要があります – Ergec

+0

コードを歩いて、あなたが得る順序は意味をなさない。 –

答えて

3

jQueryの3.0 "fixed" jqueryの遅延システムにより、Promises/A +仕様に従ってます。 https://jquery.com/upgrade-guide/3.0/#deferred

これは、あなたの.thenコールバックが、可否、値、または拒否された約束を返さなければならないことを意味します。 jQueryオブジェクトは可能ではありません。そのため、3.1にアップグレードしたときにコードが別々に動作するようになったのです。

1と2の.then()コールバックを修正して、最後に.promise()を追加することで適切に返すようにすると、期待どおりに動作します(これは古いバージョンでも同様です)。

/* 
 
JQuery Deferred Objects 
 
*/ 
 
var defer = $.Deferred(); 
 
var div1 = defer.then(function(value) { 
 
    return $(".div1").animate({ 
 
     width: "100%" 
 
    }, 1000).promise(); 
 
}); 
 
var div2 = div1.then(function(value) { 
 
    $("#status").append("<p>div1 done</p>"); 
 
    return $(".div2").animate({ 
 
     width: "100%" 
 
    }, 3000).promise(); 
 
}); 
 
var div3 = div2.then(function(value) { 
 
    $("#status").append("<p>div2 done</p>"); 
 
    return $(".div3").animate({ 
 
     width: "100%" 
 
    }, 2000, function() {$("#status").append("<p>div3 done</p>");}).promise(); 
 
}); 
 
var div4 = function() { 
 
    return $.Deferred(function(dfd) { 
 
     $(".div4").animate({ 
 
\t \t width: "100%" 
 
\t \t }, 1500, dfd.resolve); 
 
    }).promise().done(function() {$("#status").append("<p>div4 done</p>");}); 
 
} 
 
$.when(div1, div2, div3, div4()).then(function() { 
 
    $("#status").append("<p>all done</p>"); 
 
}); 
 
defer.resolve();
div { 
 
    width: 0px; 
 
    height: 20px; 
 
} 
 

 
.div1 { 
 
    background-color: red; 
 
} 
 

 
.div2 { 
 
    background-color: yellow; 
 
} 
 

 
.div3 { 
 
    background-color: lightblue; 
 
} 
 

 
.div4 { 
 
    background-color: gray; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<div class="div1">div1</div> 
 
<div class="div2">div2</div> 
 
<div class="div3">div3</div> 
 
<div class="div4">div4</div> 
 
<span id="status"></span>

関連する問題