Javascript 绑定承诺回调函数的`this`范围
通常,如果你不使用承诺,你可以很容易地做到Javascript 绑定承诺回调函数的`this`范围,javascript,Javascript,通常,如果你不使用承诺,你可以很容易地做到 var a = function(cb){ setTimeout(function(){ var boundCb = cb.bind({hello: 'world'}); boundCb(); }, 100); }; a(function(){ alert(this.hello); }); 这在大多数情况下并不特别有用(因为您可以传递与普通参数相同的内容),但它确实允许一些非常可读的代码和/或简单易用的接口 然而,当转换
var a = function(cb){
setTimeout(function(){
var boundCb = cb.bind({hello: 'world'});
boundCb();
}, 100);
};
a(function(){
alert(this.hello);
});
这在大多数情况下并不特别有用(因为您可以传递与普通参数相同的内容),但它确实允许一些非常可读的代码和/或简单易用的接口
然而,当转换到承诺时,它突然变得很难做到。毫不奇怪,以下不起作用(因为resolve
不是直接参考)
那么,有没有办法实现这一目标
非必要的后记:“幸运的是”在我的情况下,我想设置的
这个范围已经与这个范围位于a()
的范围相同。因此,我目前只是在每一个Promise回调函数之后编写.bind(this)
,将来我将能够使用arrow函数来实现这一点,但我正在寻找一个更干净的解决方案 本机承诺不提供此功能。然而,蓝鸟承诺图书馆提供了
下面是一个示例用法
MyClass.prototype.method = function() {
return fs.readFileAsync(this.file).bind(this)
.then(function(contents) {
var url = urlParse(contents);
return this.httpGetAsync(url); // this is bound to the MyClass instance
}).then(function(result) {
// this is still bound, further down the chain.
var refined = this.refine(result);
return this.writeRefinedAsync(refined);
}).catch(function(e) {
this.error(e.stack); // Even in event handlers
});
};
MyClass.prototype.method=function(){
返回fs.readFileAsync(this.file).bind(this)
.然后(功能(内容){
var url=urlParse(内容);
返回此.httpGetAsync(url);//此文件绑定到MyClass实例
}).然后(函数(结果){
//这仍然是固定的,更进一步的链条。
var refined=此.refined(结果);
返回此.writerFinedAsync(精制);
}).catch(函数(e){
this.error(e.stack);//即使在事件处理程序中也是如此
});
};代码>是的,我担心“本机承诺不提供此功能”。在第一次检查之前,我不想匆忙下结论:)。如果他们将其添加到API中,我真的不介意,这在很多方面都很有用。Promise回调的设计考虑了无状态性this
意味着状态,这不是“干净的方式”。不要试图给它们任何状态(因为我想bind
this
scope'back'),但完全理解你所说的。在这种情况下,使用lamda表达式。他们会自动将您的this
绑定到调用方的this
>“将来我可以使用箭头函数来实现这一点,但我正在寻找一个更干净的解决方案。”因此我完全同意您的意见;-)这对我来说似乎不是个好主意。您希望在创建承诺时将其与某个此
值相关联,然后在某个完全不同的位置将该值与此
相关联?对于任何维护您的代码的人来说,这似乎是一个真正的难题,因为它破坏了API的功能。@JLRishe:从API使用的角度来看,这是很有意义的,但是您必须查看具体案例的更广泛上下文才能理解。(聚合物元件,其中,本
设计应始终指当前元件。)
MyClass.prototype.method = function() {
return fs.readFileAsync(this.file).bind(this)
.then(function(contents) {
var url = urlParse(contents);
return this.httpGetAsync(url); // this is bound to the MyClass instance
}).then(function(result) {
// this is still bound, further down the chain.
var refined = this.refine(result);
return this.writeRefinedAsync(refined);
}).catch(function(e) {
this.error(e.stack); // Even in event handlers
});
};