![](/img/trans.png)
[英]jQuery Deferred/Promises dynamic array not executing callbacks in correct order
[英]Executing a For Loop of Promises in the Correct Order
我正在编写一个程序,该程序使用一个句子,并用数据库中的全部术语替换缩写(例如,“ hi and gm”->“ hello and good morning”,如果存储在数据库中的缩写为“ hi”->“你好”和“ gm”->“早上好”)。 原始句子存储在$('#translation')。text()中,应相应替换。
因此,我发现了如何通过使用promises来使forFull等待for循环完成每个单词的辅助功能getFullWord()之前的getFullSentence()。
问题是getFullWord()不能按顺序执行,例如,如果我登录“ i”,则会得到0、3、1、2而不是0、1、2、3。如何解决此问题? 先感谢您!
function getFullSentence(uid, sentence) {
var promises = [];
var words = sentence.split(" ");
$.each(words, function(i, word) {
promises.push(getFullWord(uid, word, i));
});
$.when.apply(null, promises).done(function() {
play($('#translation').text());
});
}
function getFullWord(uid, word, i) {
var defer = $.Deferred();
$.get("/checkAbbreviation/" + uid + "/" + word, function(data) {
word = data.full;
var currSentence = $('#translation').text() + " ";
var newSentence = currSentence + word.toUpperCase();
$('#translation').text(newSentence);
}).done(function() {
defer.resolve();
});
return defer.promise();
}
这里有很多错误。 首先,您不需要按顺序运行操作(就像您似乎认为的那样)。 您可以并行运行它们,并让$.when()
依次为您收集结果。 这仅要求您在收集所有结果之后最后进行所有处理,并且$.when()
将为您收集它们。
其次,您使用的是递延反模式,您可以在已返回承诺的事物周围创建承诺。 您可以直接从$.ajax()
返回诺言,而不必创建一个新的诺言。
其他一些改进:
.map()
替换.each()
和.push()
。 .join()
连接所有字符串。 $.ajax()
上的.then()
处理程序返回一个值,它将极大地简化$.when()
结果的处理。 在这种情况下,您无论如何都要返回data.full.toUpperCase()
。 .then()
,而不使用.done()
。 $.ajax()
不要混用回调和承诺。 使用其中之一(可能是最好的承诺)。 这是一种并行运行操作并按顺序收集结果的方法:
function getFullSentence(uid, sentence) {
var promises = sentence.split(" ").map(function(word, i) {
return getFullWord(uid, word, i);
});
$.when.apply($, promises).then(function() {
// get all results into an array
var results = Array.prototype.slice.call(arguments);
var text = results.join(" ");
$('#translation').text(text);
play(text);
});
}
function getFullWord(uid, word, i) {
return $.get("/checkAbbreviation/" + uid + "/" + word).then(function(data) {
// make resolved value be data.full
return data.full.toUpperCase();
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.