使用其他解决方案是否有任何意义可以使这更优雅(jquery很好)?
在我的情况下,重要的是只有先前的终止被触发才会触发相应的执行。
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
item one
item one
item two
item two
item three
item three
item four
item four
item five
item five
Done
假设输出应该是:
String1
答案 0 :(得分:2)
这是使用reduce
的理想候选人。此外,您最初的承诺 - 您希望立即解决 - 可以只是$.when()
,并且将成为reduce
来电的起始值:
seqExe(["item one", "item two", "item three", "item four", "item five"])
function seqExe(corpus) {
return corpus.reduce(function (p, item) {
return p.then(function () {
console.log(item + ' pending');
return foo(item);
});
}, $.when())
.then(function(){
console.log("Done");
}, function(){
console.log("Failed");
});
}
function foo(item) {
var defer = new $.Deferred();
window.setTimeout(
function() {
defer.resolve()
console.log(item + ' resolved');
}, Math.random() * 2000 + 1000);
return defer.promise();
}
&#13;
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
&#13;
请注意,在某些jQuery版本中(我在2.1.1中看到),then
回调是同步执行的,这会产生错误的输出顺序。这是在jQuery 3中修复的(我尝试了3.1.1,我也在上面的代码片段中链接过)。
以下是使用原生ES6承诺的方法:
seqExe(["item one", "item two", "item three", "item four", "item five"])
function seqExe(corpus) {
return corpus.reduce(function (p, item) {
return p.then(function () {
console.log(item + ' pending');
return foo(item);
});
}, Promise.resolve())
.then(function(){
console.log("Done");
}, function(){
console.log("Failed");
});
}
function foo(item) {
return new Promise(function (resolve) {
window.setTimeout(function() {
resolve();
console.debug(item + ' resolved');
}, Math.random() * 2000 + 1000);
});
}
&#13;