this - 在 AngularJS 的 promise 中使用它

标签 this bind promise

是否有一个最佳实践解决方案可以在这个范围内使用?在 jQuery 中,我可以绑定(bind)我的对象以在我的 promise /回调中使用它 - 但在 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
        });
    }
}];

这个问题有解决方案吗?我如何在 promise 范围内从我的服务中获得成员或方法的访问权限?

先感谢您。

最佳答案

动态的通用问题this在回调中解释 in this answer这非常好——我不会重复菲利克斯所说的话。我将讨论 promise 的具体解决方案:

Promise 是在 Promises/A+ 规范下指定的,它允许 Promise 库无缝地使用彼此的 Promise。 Angular $q promise 尊重该规范,因此,Angular promise 必须根据定义执行 .then回调函数 - 即没有设置 this .在严格模式下做 promise.then(fn)将始终评估 thisfn 内部未定义(以及到 window 在非严格模式下)。

理由是 ES6 横空出世,更优雅地解决了这些问题。

那么,您有哪些选择?

  • 一些 Promise 库提供了 .bind方法(例如 Bluebird),您可以 use these promises inside Angular并换出 $q。
  • ES6、CoffeeScript、TypeScript 和 AtScript 都包含 =>绑定(bind) this 的运算符.
  • 您可以通过 .bind 使用 ES5 解决方案
  • 您可以使用 Felix 上述答案中的一种技巧。

  • 以下是这些示例:

    添加绑定(bind) - 又名 Promise#bind
    假设您已关注 above question and answer你应该能够做到:
    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
    Restangular.one('me').get().then(function(response) {
        this._myVariable = true; // this is correct
    }.bind(this));
    

    使用 ES5 之前的“hack”
    var that = this;
    Restangular.one('me').get().then(function(response) {
        that._myVariable = true; // this is correct
    });
    

    当然还有一个更大的问题

    您当前的设计不包含任何方式来_知道何时_myVariable可用。您必须对其进行轮询或依赖内部状态排序。我相信您可以做得更好,并设计一个在变量可用时始终执行代码的设计:
    app.service('exampleService', ['Restangular', function(Restangular) {
        this._myVariable =Restangular.one('me');
    }];
    

    然后你可以使用 _myVariable通过 this._myVariable.then(function(value){ .这可能看起来很乏味,但如果您使用 $q.all您可以使用多个值轻松完成此操作,这在状态同步方面是完全安全的。

    如果你想延迟加载它而不是第一次调用它(也就是说,只有在调用 myFunction 时)——我完全明白。您可以使用 setter/getter 并执行以下操作:
    app.service('exampleService', ['Restangular', function(Restangular) {
        this.__hidden = null;
        Object.defineProperty(this,"_myVariable", {
          get: function(){ 
            return this.__hidden || (this.__hidden = Restangular.one('me')); 
          }
        });
    }];
    

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

    关于this - 在 AngularJS 的 promise 中使用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26903430/

    相关文章:

    javascript - AngularJS V1.1 拦截器总是在末尾有 $q.when

    javascript - 如何将变量绑定(bind)到函数调用

    javascript - 异步失败时更喜欢抛出或拒绝

    javascript - 为什么 "this"关键字在这里不起作用?

    javascript - IE 在 JavaScript 中的 "self = this"上抛出异常?

    jQuery $(this) 语法问题

    jquery 重新声明 $(this)

    JavaScript `bind` 无法处理导入的函数/对象

    c++ - 地址已在使用中。

    comparison - Volt 迭代与 Promise 的比较