繁体   English   中英

以正确的顺序执行承诺的循环

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM