jQuery deferred 适用于 jQuery v1.x 和 v2.x 但不适用于 v3.x

jQuery deferred works with jQuery v1.x and v2.x but not with v3.x

这个fiddle是关于jquery延迟对象的。执行顺序是 1,4,2,3 。它按预期工作 jquery v1.xv2.x 但不是 v3.x 。我错过了什么?

正确的顺序是 1,4,2,3,all done 但在 v3 中是 1,2,4,all done,3 这没有意义 when/all done3

之前触发

只需更改 jQuery 版本,您就会发现 v3.x1,4,2,3 顺序中不起作用。

fiddle

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;
}

javascript

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>

jQuery 3.0 "fixed" jquery 延迟系统,以便它更紧密地遵循 Promises/A+ 规范。 https://jquery.com/upgrade-guide/3.0/#deferred

这意味着现在您的 .then 回调必须 return 一个 thenable、一个值或一个被拒绝的承诺。 jQuery 对象不可用,这就是为什么您的代码在升级到 3.1 后开始以不同方式工作的原因。

如果您通过在末尾添加 .promise() 来修改 1 2 和 3 的 .then() 回调以正确 return 一个 thenable,它将返回到预期的工作状态(这在旧版本也一样。)

/*
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({
  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();
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>