尽管有箭头功能,但无法访问 then() 中的值范围

Can't access scope of value in then() despite arrow function

在这个 class 的 angular 组件中,我遇到了一个我不明白的范围问题。

class ConnectionsComponent {
  constructor($http, $q) {
    this.$http = $http;
    this.$q = $q;
    this.listGotten = [];
    this.arrayOfGets = ['id1', 'id2', 'id3'];
  }

  $onInit() {
    var promises = [];

    angular.forEach(this.arrayOfGets, getThis => {
      var promise = this.$http.get('/api/endpoint/' + getThis)
      promises.push(promise)
    }) // end angular.forEach

    this.$q.all(promises).then((data) => {
      this.listGotten = data;
      console.log(this.listGotten) // <-- prints array of objects
    })

      console.log(this.listGotten) // <-- empty array (PROBLEM!)    

  } // end $oninit

} // end class

根据 this post,这应该不是问题,因为我使用的是将范围传递到 then() 的箭头函数。它不是 undefined,它只是一个空数组,就好像 this.listGotten 从未被分配过 data 一样。

这是时间问题。您的 .then() 处理程序称为 LATER,因为它代表所有异步操作的完成。而您的:

console.log(this.listGotten) // <-- empty array (PROBLEM!)  

在您的 .then() 处理程序甚至 运行 之前执行,因此 this.listGotten 尚未设置。您的箭头功能按预期工作 - 这不是与此相关的问题。

如果您在代码中加入一些 console.log() 语句来查看像这样的事情的实际时间:

  $onInit() {
    var promises = [];
    console.log("1 - start");   
    angular.forEach(this.arrayOfGets, getThis => {
      var promise = this.$http.get('/api/endpoint/' + getThis)
      promises.push(promise)
    }) // end angular.forEach

    console.log("2 - about to do .all()");
    this.$q.all(promises).then((data) => {
      console.log("3 - inside .then() handler");
      this.listGotten = data;
      console.log(this.listGotten) // <-- prints array of objects
    })

      console.log("4 - after .then() handler");
      console.log(this.listGotten) // <-- empty array (PROBLEM!)    

  } // end $oninit

然后,你会看到这个输出:

1 - start
2 - about to do .all()
4 - after .then() handler
3 - inside .then() handler

因此,您可以看到您的 .then() 处理程序在您的其他 console.log() 执行之后被调用。

异步结果的解决方案是 "use them in the callback where they are presented",因为这是您知道它们存在时间的唯一地方。

请记住在异步代码中,您所有的 $http.get() 操作只是启动 http 请求,然后它们 运行 在后台进行。 Javascript 的其余部分继续 运行 一段时间后,您的异步请求将完成并调用它们的回调,在您的其余代码执行完很久之后。

发生这种情况是因为 this.$q.all 它本身是一个承诺(异步),当所有输入承诺都得到解决时,它就会得到解决。所以,当你这样写的时候:

this.$q.all(promises).then((data) => {
  this.listGotten = data;
  console.log(this.listGotten) // <-- prints array of objects
})

//This will be executed before the $q.all is resolved or rejected !
//or at least will not wait for $q.all to finish
console.log(this.listGotten) // <-- empty array (PROBLEM!)