Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 以不同的方式等待承诺_Javascript_Jquery_Promise_Jquery Deferred_Deferred - Fatal编程技术网

Javascript 以不同的方式等待承诺

Javascript 以不同的方式等待承诺,javascript,jquery,promise,jquery-deferred,deferred,Javascript,Jquery,Promise,Jquery Deferred,Deferred,我目前正在努力实现承诺,我认为我的概念有点错误。基本上我要做的是编写一个小的模板处理程序 它有一个load()方法,该方法加载模板并将其存储到属性中,它将是可链接的。我想使用的链接方法是attachTo()with将我之前加载的模板附加到DOM元素 由于模板是异步加载的,所以我尝试使用承诺。但是promise上的done()方法似乎在异步调用完成之前立即启动 我这样称呼它: tpl.load('stuff.html').attachTo($('.someElement')) 我希望它的行为是,每

我目前正在努力实现承诺,我认为我的概念有点错误。基本上我要做的是编写一个小的模板处理程序

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

由于模板是异步加载的,所以我尝试使用承诺。但是promise上的
done()
方法似乎在异步调用完成之前立即启动

我这样称呼它:

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

我希望它的行为是,每当我调用
attachTo()
时,它都会等待我以前调用的load()方法完成异步操作,然后启动
done
方法中提供的回调

下面是处理程序的相关部分

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'));

事实证明,这是一个范围界定问题。延迟没有什么问题,但我将值分配给的实例的范围有问题

load: function(template) {
    this.promise = $.get(this.templateUrl + template, function(response){
        this.template = response;
        console.log(this.template);
        //Outputs the desired value
    });
    return this;
},
在这里,我给这个.template分配了一个值。但是我不在我的对象的范围内,而是在
$.get()
方法的闭包范围内。因此,其他方法无法从属性中提取该值,因为它从未存储在那里

我想到了:

load: function(template) {
    var self = this;
    this.promise = $.get(this.templateUrl + template, function(response){
        self.template = response;
    });
    return this;
},
我首先将对象实例分配给
self
变量,并在闭包中引用它,而不是使用
this
。为了更优雅地解决这个问题,还可以使用一个


就这些。这只是一个范围问题,而不是一个延迟的问题。

虽然您自己已经确定了问题,但建议的解决方案不是一个好的解决方案

您不应该使用在某个时间设置的全局变量,并且只使用承诺来传播更改,但是承诺应该表示这些值。这将导致更好的函数式编程风格

就你而言:

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

这看起来很正常,可能您收到了一个错误(不管结果类型如何,都会调用done)。尝试使用this.promise.then().fail()方法来区分请求结果的好坏。谢谢@PeterAronZentai。确实是我的错。当我设置模板属性时,我把范围搞乱了。这不再指我的对象,而是指回调的范围。只是需要使用代理。谢谢你指出这个问题!我不确定你的代码现在有什么问题?请澄清一下?@BenjaminGruenbaum它已经解决了(请参阅我上面的评论:)但是肯定。问题是,我认为promise上的
done()
方法是在我的
load()
方法中的异步请求被处理后启动的,因为我的
模板
属性是空的,尽管它应该由load方法中的ajax请求填充。最终发现这只是一个范围问题,与延期无关。如果问题已经解决,请将问题恢复到原来的状态,并发布一个关于如何解决问题的答案,而不是在中进行编辑。