【问题标题】:ES6 and variable scope inside a promiseES6 和 promise 中的变量范围
【发布时间】:2016-11-30 07:27:04
【问题描述】:

不确定我在这里缺少什么。

我需要将data 的输出转换为this.contact。现在,我正在使用静态类变量,但必须这样做似乎很脏。

export class contactEdit {
  static t; // static class var
  constructor() {
    this.id = null;
    this.contact = null;
    contactEdit.t = this;
  }

  activate(id) {
    this.id = id;
    let contact = this.contact; // scoped version of class var
    return dpd.contacts.get(id).then(function(data) {
      console.log(data);
      contactEdit.t.contact = data; // this works
      contact = data; // this doesn't
    });
  }
}

通常我会在 activate() 函数中创建一个 var contact(它在 Chrome 控制台中有效),但这似乎不适用于 ES6。

Chrome 控制台:

var c = null;
undefined
c;
null
dpd.contacts.get('a415fdc8f5a7184d').then(function(data) {
      c = data;
    });
Object {}fail: (n)then: (e,t)__proto__: Object
c;
Object {firstName: "John", lastName: "Doe", id: "a415fdc8f5a7184d"}

【问题讨论】:

  • 你不只是想要this.contact = data;而不是contact = data;吗?
  • static t; 不是 ES6。你在用打字稿还是什么的?
  • 无论如何,您都不应该将 Promise 结果存储为实例属性。如果需要,请存储 promise。
  • @trincot no, this 在 Promise 中不再引用类。那是我的第一次尝试:)
  • @Bergi,不是打字稿。不过,一些实验性功能已开启。

标签: promise ecmascript-6 aurelia deployd


【解决方案1】:

你需要做两件事。一是使用箭头函数,二是使用`this.contact = data;

activate(id) {
  this.id = id;
  return dpd.contacts.get(id).then(data => {
    console.log(data);
    this.contact = data;
  });
}

您使用箭头函数是因为它处理 JavaScript 的“this”问题,其中 this 指的是函数的词法范围,而不是您当前所在的对象。使用箭头函数可确保 @987654324箭头函数外的@与箭头函数内的this相同。

您需要使用this.contact,因为contact 是该类的实例属性。

【讨论】:

  • 今天所有堆栈溢出的最佳答案
  • @MatthewJamesDavis 我同意,箭头函数可以解决问题。
  • @AshleyGrant,也许您可​​以添加一两句话说明为什么箭头功能可以解决此问题?我将继续阅读此内容,但我敢肯定会帮助其他人。
  • 其他对细节感兴趣的人,请参阅此处的 Lexical This section:developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
【解决方案2】:

问题是contact = data;会更新本地contact变量的值,但不会改变this.contact的值。 您需要改为更新 contact 联系人属性。问题是您无权访问匿名函数体内的this(或者更确切地说,匿名函数的thisactivatethis 不同)。

有不同的方法来解决这个问题。

1- 您可以将activate的上下文(this)保存到activate的闭包中的一个变量中,以便您可以在then的核心内访问它。

activate(id) {
    this.id = id;
    let that = this;
    return dpd.contacts.get(id).then(function(data) {
      console.log(data);
      that.contact = data;
    });
  }

2- 您可以将函数绑定到activatethis,以便使用相同的上下文调用它。

activate(id) {
    this.id = id;
    return dpd.contacts.get(id).then(function(data) {
      console.log(data);
      this.contact = data;
    }.bind(this));
  }

3-(在 ES6 中推荐)您可以使用箭头函数(箭头函数没有自己的上下文,因此它们保留了创建它们的位置)

activate(id) {
    this.id = id;
    return dpd.contacts.get(id).then((data) => {
      console.log(data);
      this.contact = data;
    });
  }

【讨论】:

  • 我已经尝试了#1,但没有运气。尝试#2 看看它是如何工作的。 #3 有效。
  • #1 和#2 也可以。我的错误是使用let contact = this.contact。显然,这在let that = this 工作的地方不起作用。奇怪,但我会接受的。
  • 这并不奇怪。如果您执行contact = something,您正在为contact 变量 分配一个新值。您没有修改分配给它的先前值。您要做的是更改 contact 对象的 this 属性。此属性与contact 变量无关(除了您将其值初始化为this.contact 指向的值这一事实之外)。更改对象obj 的属性prop 指向的值的唯一方法是编写类似于obj.prop = something 的内容。
猜你喜欢
  • 1970-01-01
  • 2016-05-14
  • 1970-01-01
  • 2014-01-31
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 1970-01-01
相关资源
最近更新 更多