我正在编写一个程序,它接受一个句子并用数据库中的完整术语替换缩写(例如,“hi and gm” - >“hello and good morning”如果存储在数据库中的缩写是“hi” - >“你好”和“gm” - >“早上好”)。原始句子存储在$('#translation')。text()中,应该相应替换。
所以我发现如何让getFullSentence()等到for循环使用promises为每个单词完成辅助函数getFullWord()。
问题是getFullWord()没有按顺序执行,例如如果我记录“我”我得到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();
}
答案 0 :(得分:1)
这里有很多错误。首先,您不需要按顺序运行您的操作(就像您认为的那样)。您可以并行运行它们,让$.when()
按顺序收集结果。这只需要您在收集完所有结果后在最后完成所有处理,$.when()
将为您收集它们。
其次,您正在使用延迟反模式,您可以在已经返回承诺的事物周围创建承诺。您可以直接从$.ajax()
返回承诺,而不是创建新承诺。
其他一些改进:
.map()
替换.each()
和.push()
。.join()
加入所有字符串。.then()
上的$.ajax()
处理程序返回值,则会极大地简化$.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();
});
}