【问题标题】:jQuery deferred works with jQuery v1.x and v2.x but not with v3.xjQuery deferred 适用于 jQuery v1.x 和 v2.x,但不适用于 v3.x
【发布时间】:2017-03-25 22:25:09
【问题描述】:

这个小提琴是关于 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.x 无法按照 1,4,2,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;
}

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>

【问题讨论】:

  • 它工作正常。您可能包含了错误的 3.x 版本(精简版没有所有方法)
  • @KevinB 顺序不同,必须是1,4,2,3,all done。但是在v3 中它是1,2,4,all done,3,这没有意义when/all done3 之前触发。全部完成后必须在末尾​​span>
  • 浏览代码,你得到的顺序是有意义的。
  • 你需要正确地从你的 .then 过滤器返回承诺,如果你希望每个人都等待前一个。 jsfiddle.net/mrd2dt3a/7
  • @KevinB 现在很好用。您可以将其发布为答案,以便我接受。谢谢。

标签: jquery promise jquery-deferred deferred


【解决方案1】:

jQuery 3.0 “修复” jquery 延迟系统,使其更接近 Promises/A+ 规范。 https://jquery.com/upgrade-guide/3.0/#deferred

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

如果您修改 1 2 和 3 的 .then() 回调以通过在末尾添加 .promise() 来正确返回 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多