在AngularJS的承诺中使用它

时间:2014-11-13 07:24:15

标签: this bind promise

是否有最佳实践解决方案能够在承诺中使用?在jQuery中,我可以绑定我的对象以在我的promise / callback中使用它 - 但是在angularJS中?有最佳实践解决方案吗? “var service = this;”的方式我不喜欢......

app.service('exampleService', ['Restangular', function(Restangular) {
    this._myVariable = null;

    this.myFunction = function() {
        Restangular.one('me').get().then(function(response) {
            this._myVariable = true; // undefined
        });
    }
}];

这个问题有解决方案吗?如何在承诺范围内从我的服务中获取成员或方法?

提前谢谢。

1 个答案:

答案 0 :(得分:20)

回调中动态this的一般问题被解释为in this answer,这非常好 - 我不会重复Felix所说的内容。我将讨论承诺特定的解决方案:

Promises在Promises / A +规范下指定,允许promise库无缝地使用彼此的promise。 Angular $ q承诺尊重规范及其角色和Angular承诺必须按定义执行.then回调作为函数 - 即没有设置this。在严格模式下,执行promise.then(fn) 总是 评估thisfn内部未定义(以及非严格模式下的window)。

理由是ES6即将到来,更优雅地解决了这些问题。

那么,你有什么选择?

  • 某些承诺库提供.bind方法(例如Bluebird),您可以use these promises inside Angular并换出$ q。
  • ES6,CoffeeScript,TypeScript和AtScript都包含一个绑定=>的{​​{1}}运算符。
  • 您可以使用this
  • 来使用ES5解决方案
  • 您可以使用Felix上述答案中的一个黑客攻击。

以下是这些例子:

添加bind - 又名.bind

假设您已经按照above question and answer进行了操作:

Promise#bind

使用箭头功能

Restangular.one('me').get().bind(this).then(function(response) {
    this._myVariable = true; // this is correct
});

使用Restangular.one('me').get().then(response => { this._myVariable = true; // this is correct });

.bind

使用前ES5'黑客'

Restangular.one('me').get().then(function(response) {
    this._myVariable = true; // this is correct
}.bind(this));

当然,还有一个更大的问题

var that = this; Restangular.one('me').get().then(function(response) { that._myVariable = true; // this is correct }); 可用时,您当前的设计不包含_know的任何方式。您必须轮询它或依赖内部状态排序。我相信你可以做得更好,并且有一个设计,当变量可用时你总是执行代码:

_myVariable

然后您可以通过app.service('exampleService', ['Restangular', function(Restangular) { this._myVariable =Restangular.one('me'); }]; 使用_myVariable。这可能看起来很乏味但是如果你使用this._myVariable.then(function(value){,你可以轻松地使用几个值来完成这个操作,这在状态同步方面是完全安全的。

如果你想延迟加载它而不是第一次调用它(也就是说,只有在调用myFunction时) - 我完全明白了。您可以使用getter并执行:

$q.all

现在,只有在您第一次访问它时才会延迟加载。