等待不同方法的承诺

时间:2014-04-17 09:24:16

标签: javascript jquery promise jquery-deferred deferred

我目前正在努力应对承诺,我认为这个概念有点不对劲。基本上我要做的是编写一个小模板处理程序。

它有一个load()方法,它加载模板并将其存储到属性中,并且它是可链接的。我希望将其链接的方法是attachTo(),并将之前加载的模板附加到DOM元素。

由于模板是异步加载的,我试图使用promises。但似乎承诺上的done()方法立即触发,并且在异步调用完成之前。

我称之为:

tpl.load('stuff.html').attachTo($('.someElement'));

我希望它表现的是,每当我调用attachTo()时,它将等待我之前调用的load()方法来完成异步操作,然后触发{{1}中提供的回调方法。

这是处理程序的相关部分

done

2 个答案:

答案 0 :(得分:1)

原来这是一个范围问题。延迟没有任何问题,但是我将实例的范围分配给了。

load: function(template) {
    this.promise = $.get(this.templateUrl + template, function(response){
        this.template = response;
        console.log(this.template);
        //Outputs the desired value
    });
    return this;
},

我在这里为this.template分配了一个值。但是我不在我的对象的范围内,而是在$.get()方法的闭包范围内。因此,其他方法无法将值从属性中拉出,因为它从未存储在那里。

我想出了:

load: function(template) {
    var self = this;
    this.promise = $.get(this.templateUrl + template, function(response){
        self.template = response;
    });
    return this;
},

我首先将对象实例实例分配给self变量,并在闭包内引用它,而不是使用this。为了更优雅地解决它,也可以使用$.proxy()

这就是全部。这只是一个范围而不是延期问题。

答案 1 :(得分:1)

虽然您已经自己发现了问题,但建议的解决方案并不是很好。

您不应该使用在某些时候设置的全局变量,并且仅使用promises来传播更改,但承诺应表示这些值。这导致了更好的功能性编程风格。

在你的情况下:

var tpl = {
    …
    templatePromise: null,
    load: function(template) {
        this.templatePromise = $.get(this.templateUrl + template).then(function(response) {
            console.log(this.template);
            //Outputs the desired value
            return response;
        });
        return this;
    },
    attachTo: function(el) {
        $.when(this.templatePromise).done(function(template) {
            // get the template here:              ^^^^^^^^
            console.log(template);
        });
    }
    …
}