这里我尝试按顺序加载几个JS文件。问题是$.when
不等待链完成。但是最后一个$.Deferred.then
按预期工作。我该怎么做才能让$.when
工作?
var urls = [
"https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js",
"https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe.js",
"https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe-ui-default.js"
];
var xxx = $.Deferred();
xxx.then(function() {
options = {
dataType: "script",
url: urls[0],
cache: false
};
return $.ajax(options).promise();
})
.then(function() {
options = {
dataType: "script",
url: urls[1],
cache: false
};
return $.ajax(options).promise();
})
.then(function() {
options = {
dataType: "script",
url: urls[2],
cache: false
};
return $.ajax(options).promise();
}).then(function() {
$("body").append("This is correct. All files are loaded.<br>");
});
$.when(xxx).done(function() {
$("body").append("This is wrong. JS files are not loaded yet.<br>");
});
xxx.resolve();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
&#13;
答案 0 :(得分:1)
您的方法不起作用,因为您创建了相同承诺的两个分支。你有相当于:
var xxx = $.Deferred();
xxx.then(...).then(...); // promise chain 1
xxx.then(...) // promise chain 2
xxx.resolve(); // start the race between the two promise chains
这只是两个单独的承诺链之间的竞争,这些承诺链没有排序或协调。无论哪个花费较少的时间执行都将首先达到目的。他们之间没有协调。
有关详细说明,请参阅Chaining vs. Branching和p.then().then() vs. p.then(); p.then()。
而且,您对$.when(xxx).done()
的使用是不必要的,根本不是问题的一部分。您可以使用xxx.done()
获得相同的结果。
您只需使用一个保证链即可修复它:
p.then(...).then(...).then(...)
然后,一切都正确排序和协调。
var urls = [
"https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js",
"https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe.js",
"https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe-ui-default.js"
];
let options = {
dataType: "script",
url: urls[0],
cache: false
};
$.ajax(options).then(function() {
let options = {
dataType: "script",
url: urls[1],
cache: false
};
return $.ajax(options);
}).then(function() {
let options = {
dataType: "script",
url: urls[2],
cache: false
};
return $.ajax(options).then(function() {
$("body").append("Last script loaded<br>");
});
}).then(function() {
$("body").append("This is correct. All files are loaded.<br>");
});
工作示例:https://jsfiddle.net/jfriend00/tLp68a3q/
或者,如果您仍想使用var xxx = $.Deferred()
初始化您的链,以便稍后可以使用xxx.resolve()
启动它,那么您也可以这样做,但是您无法使用xxx.then()
或$.when(xxx)
,因为这是一个完全独立的分支,根本没有链接到另一个承诺链。
以$.Deferred()
开头的工作示例:https://jsfiddle.net/jfriend00/y5n3hb99/