简体   繁体   English

用不同的方法等待 promise

[英]Waiting for promises in different methods

I'm currently struggling with promises and I think I got the concept a bit wrong.我目前正在为承诺而苦苦挣扎,我认为我的概念有点错误。 Basically what I am trying to do is writing a little template handler.基本上我想做的是编写一个小模板处理程序。

It has a load() method which loads a template and stores it into a property and it is going to be chainable.它有一个 load() 方法,它加载一个模板并将其存储到一个属性中,并且它将是可链接的。 The method I want to chain it with is attachTo() with appends the template I loaded before to a DOM element.我想链接它的方法是attachTo() ,将我之前加载的模板附加到 DOM 元素。

Since the template is loaded asynchronously I tried to use promises.由于模板是异步加载的,我尝试使用 Promise。 But it seems that the done() method on the promise is firing immediately, and before the async call has been finished.但似乎 promise 上的done()方法正在立即触发,并且在异步调用完成之前。

I call it like that:我这样称呼它:

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

What I want it to behave is, that whenever I call attachTo() it will wait for my previously called load() method to get it's asynchronous stuff done, and then fire the callback provided in the done method.我希望它的行为是,每当我调用attachTo()它都会等待我之前调用的 load() 方法来完成它的异步操作,然后触发done方法中提供的回调。

Here's the relevant part of the handler这是处理程序的相关部分

var tpl = {
...
    template: null,
    promise: null,

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

    attachTo: function(el) {
        var self = this;
        $.when(this.promise).done(function(){
            //outputs null but should output the 
            //value that has been set in my async call
            console.log(self.template);
        });
    }

..
}

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

It turned out that it was a scoping problem.结果证明这是一个范围界定问题。 There was nothing wrong with the deferreds but with the scope of the instance I assigned the value to. deferreds 没有任何问题,但是我分配了值的实例的范围。

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

Here I assigned a value to this.template .在这里,我为this.template分配了一个值。 But I was not in the scope of my object but in the scope of the closure of the $.get() method.但是我不在我的对象范围内,而是在$.get()方法的关闭范围内。 Hence other methods cannot pull the value out of the property because it was never stored there.因此,其他方法无法从属性中提取值,因为它从未存储在那里。

I came up with:我想出了:

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

I first assigned the object instance instance to the self variable and refered to it inside the closure instead of using this .我首先将对象实例实例分配给self变量并在闭包中引用它而不是使用this To solve it more elegantly also a $.proxy() could have been used.为了更优雅地解决它,还可以使用$.proxy()

That's all.就这样。 It was just a scoping and not a deferred issue.这只是一个范围界定问题,而不是一个延期问题。

While you have identified the problem yourself already, the proposed solution is not a good one.虽然您自己已经确定了问题,但建议的解决方案并不是一个好的解决方案。

You should not use global variables that are set somewhen and use promises just for propagating changes, but the promises should represent these values.你不应该使用在某个时候设置的全局变量,也不应该使用承诺只是为了传播更改,但承诺应该代表这些值。 This leads to a better, functional programming style.这导致了更好的函数式编程风格。

In your case:在你的情况下:

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);
        });
    }
    …
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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