绑定一个promise回调函数的`this`范围

Dav*_*der 5 javascript

通常,如果你没有使用承诺,你可以很容易地做到

var a = function(cb){
  setTimeout(function(){
    var boundCb = cb.bind({hello: 'world'});
    boundCb();
  }, 100);
};

a(function(){
  alert(this.hello);
});
Run Code Online (Sandbox Code Playgroud)

这在大多数时候都不是特别有用(因为你可以传递与普通参数相同的东西),但它确实允许一些非常易读的代码和/或简单易用的接口.

然而,当转换到承诺时,突然变得更加困难.不出所料,以下不起作用(因为resolve不是直接参考)

var a = function(){
  return new Promise(function(resolve, reject){
    var boundResolve = resolve.bind({hello: 'word'});
    boundResolve();
  });
};

a().then(function(){
  alert(this.hello)
});
Run Code Online (Sandbox Code Playgroud)

那有什么办法可以达到这个目的吗?


非必要的postscriptum:'幸运'在我的情况下,this我想设置的范围已经与this范围相同a().所以我目前只是.bind(this)在每个Promise回调函数之后编写,并且将来我将能够使用箭头函数,但我正在寻找一个更清洁的解决方案.

Mad*_*iha 4

Native Promise 不提供此功能。然而,Bluebird Promise 库提供了Promise.prototype.bind

这是一个示例用法

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
    });
};
Run Code Online (Sandbox Code Playgroud)

  • Promise 回调在设计时考虑到了无状态性。`this` 意味着状态,这不是“干净的方式”。 (3认同)