Javascript 以不同的方式等待承诺
我目前正在努力实现承诺,我认为我的概念有点错误。基本上我要做的是编写一个小的模板处理程序 它有一个load()方法,该方法加载模板并将其存储到属性中,它将是可链接的。我想使用的链接方法是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')) 我希望它的行为是,每
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请求填充。最终发现这只是一个范围问题,与延期无关。如果问题已经解决,请将问题恢复到原来的状态,并发布一个关于如何解决问题的答案,而不是在中进行编辑。