【问题标题】:Promise: avoid forking/splitting and chain first this then do this承诺:避免分叉/分裂和链先这个然后做这个
【发布时间】:2016-11-02 18:14:14
【问题描述】:

这是现在的代码,promise 链和以前一样。我已经开始尝试使用 Promise.all() 来摆脱反模式

(function(){
'use strict';

function DOMObj(){
    var that = this;

    that.items = [];

    that.getitems = function(url) {
        return new Promise (resolve => {
                $.getJSON(url, function (response) {
                    for (var i = 0; i < response.sales.length; i++) {

                        that.items.push(new ProductObj(response.sales[i], i));

                    }
                    resolve();
                });
            }
        )
    };

    that.updateProductHTML = function(){
        return new Promise(resolve => {
            for( var i = 0; i < that.items.length; i++){

                that.items[i].updateHTML();

            }
            resolve();
        })
    };

    that.updateDOM = function() {
        return new Promise(resolve => {
            var thisHTML = '';

            for( var i = 0; i < that.items.length; i++) {

                if (i % 3 === 0 ) {
                    thisHTML += "<div class='row'>";
                    // console.log("START");
                }

                thisHTML += that.items[i].htmlView;

                if ((i % 3 === 2) || i === (that.items.length - 1) ) {
                    thisHTML += "</div>";
                     console.log("FINISH");
                }
            }
            $("#content").append(thisHTML);
            resolve();
        })
    }
}

function ProductObj(product, i) {
    var that = this;

    that.photo = product.photo;
    that.title = product.title;
    that.subtitle = product.subTitle;
    that.url = product.url;

    that.htmlView = "";
    that.index = i;


    that.updateHTML = function() {
        $.get('template.html', function(template){
            that.htmlView = template.replace('{image}', that.photo)
                .replace('{title}', that.title)
                .replace('{subtitle}', that.subtitle)
                .replace('{url}', that.url);

             console.log(that.index + ' product has worked through html')
        })
    };
}
var myView = new DOMObj();

myView.getitems('data.json')
    .then(
        myView.updateProductHTML
    )
    .then(
        myView.updateDOM()
    )
    .then(() =>{
        $('.deleteButton').click(() => {
            $(this).parent().remove();
        });

//Promise.all([ myView.getitems('data.json'), myView.updateProductHTML, myView.updateDOM, () => {$('.deleteButton').click(() => {
    //$(this).parent().remove();
//})}])

})();

到目前为止,代码按此顺序运行 getItems =&gt; updateProductHTML 然后 updateDOM 运行,我尝试添加的最后一个代码是按钮上的单击事件,显然需要最后运行

【问题讨论】:

  • 请向我们展示您的实际代码。不要说“我的承诺是这样设置的”,然后向我们展示可怕的损坏(伪?)代码。
  • this.updateHTML 看起来是异步的,是的,但它实际上需要 return $.get 承诺才有用!
  • 那是代码跳过者
  • 好吧,但这是您遇到问题的代码,所以请不要跳过它。
  • 不是实际代码

标签: javascript jquery ecmascript-6


【解决方案1】:

将您的函数更改为返回一个将在回调函数完成时解决的承诺:

this.updateHTML = function() {
    return new Promise(resolve => {
        $.get('product-template.html', function(template) {
            this.htmlView = template.replace('{image}', this.photo)
                .replace('{string1}', this.string1)
                .replace('{string2}', this.string2)
                .replace('{url}', this.URL)
                .replace('{class}', this.class);
            resolve();
        });
    });
};

getData() 也一样。


那么您应该能够轻松地链接这些步骤:

getData().then(updateHTML).then(updateDOM);

【讨论】:

  • 好的,我可以同时得到 getData => updateProductHTML 和 updateDOM。我不能将承诺放到 updateHTML 中,因为它在另一个 for 循环中,所以 thenable 无法访问它。我把它放在我的 for 循环中,但它运行不正确
  • @Bergi 有趣的阅读。这主要适用于getData,因为潜在的fetch 已经返回了一个承诺,而不是updateHTML,对吗?
  • 您的 updateHTML 正在使用一个承诺 - $.get(…)。它确实需要可选的回调,但总是返回一个 (jQuery) 承诺。您可以简单地 omit 它甚至将该回调放入 .then(…) 调用中。如果您不想使用 jQuery 承诺,[只需将其包装在 Promise.resolve(…) 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-15
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多