在这里,我尝试按顺序加载几个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();<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>小提琴 https://jsfiddle.net/ergec/fmrj6qgp/
Here i try to load several JS files sequentially. Problem is $.when does not wait for the chain to complete. But the last $.Deferred.then works as expected. What should i do to make $.when work?
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();<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>Fiddle https://jsfiddle.net/ergec/fmrj6qgp/
最满意答案
你的方法不起作用,因为你从同一个承诺中创建了两个分支。 你有相当于:
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与Branching和p.then()。then()与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 : $.Deferred()
Your method does not work because you create two branches off the same promise. You have the equivalent of:
var xxx = $.Deferred(); xxx.then(...).then(...); // promise chain 1 xxx.then(...) // promise chain 2 xxx.resolve(); // start the race between the two promise chainsThat is simply a race between two separate promise chains that are not sequenced or coordinated. Whichever one takes less time to execute will get to its end first. There is zero coordination between them.
See Chaining vs. Branching and p.then().then() vs. p.then(); p.then() for further explanation.
And, your use of $.when(xxx).done() is unnecessary and not really part of the issue at all. You would get the same result with xxx.done().
You can fix it by only using one promise chain:
p.then(...).then(...).then(...)Then, everything is properly sequenced and coordinated.
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>"); });Working example: https://jsfiddle.net/jfriend00/tLp68a3q/
Or, if you still wanted to initialize your chain with var xxx = $.Deferred() so you could start it later with xxx.resolve(), then you can do that too, but you can't use xxx.then() or $.when(xxx) because that is a completely separate branch that is not linked to the other promise chain at all.
Working example starting with $.Deferred(): https://jsfiddle.net/jfriend00/y5n3hb99/
更多推荐
发布评论