【问题标题】:Executing a For Loop of Promises in the Correct Order以正确的顺序执行 Promise 的 For 循环
【发布时间】:2017-02-27 08:31:53
【问题描述】:

我正在编写一个程序,它接受一个句子并用数据库中的完整术语替换缩写词(例如,“hi and gm”->“hello and good morning”,如果存储在数据库中的缩写词是“hi”- ->“你好”和“gm”->“早上好”)。原句存储在$('#translation').text()中,应相应替换。

所以我发现了如何使用 Promise 让 getFullSentence() 等到 for 循环完成每个单词的辅助函数 getFullWord()。

问题是 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();
}

【问题讨论】:

  • $.Deferred() 在getFullWord() 函数中不是必需的,.done() 返回一个 jQuery 承诺对象。 i 不用于getFullWord。您可以在问题中包含play 的文本吗?为什么getFullSentence 没有返回值?使用链接到$.get() 的.then() 而不是$.get() 回调和.done()
  • 感谢您的回复! play() 调用一个名为 ResponsiveVoice.js 的库来说出句子。 getFullSentence() 不需要返回任何东西,因为它只是调用了 play() 函数

标签: javascript jquery get promise deferred


【解决方案1】:

这里有很多问题。首先,您不需要按顺序运行操作(就像您似乎认为的那样)。您可以并行运行它们,并让$.when() 按顺序为您收集结果。这只需要您在收集完所有结果后在最后完成所有处理,$.when() 将按顺序为您收集它们。

其次,您正在使用延迟的反模式,您可以在其中围绕已经返回承诺的事物创建承诺。你可以直接从$.ajax()返回promise,而不是创建一个新的。

其他一些改进:

  • 您可以使用.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();
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 2018-10-16
    • 2022-11-23
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    相关资源
    最近更新 更多