首页 \ 问答 \ 尽管有箭头功能,但无法访问then()中的值范围(Can't access scope of value in then() despite arrow function)

尽管有箭头功能,但无法访问then()中的值范围(Can't access scope of value in then() despite arrow function)

在这个角度组件的类中,我有一个我不明白的范围问题。

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

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


In this class for an angular component I'm having a scope issue that I don't understand.

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

According to this post, it shouldn't be an issue because I'm using the arrow function which passes the scope into the then(). It's NOT undefined, it's just an empty array, as if this.listGotten never had data assigned to it.


原文:https://stackoverflow.com/questions/38413828
更新时间:2020-03-26 12:07

最满意答案

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

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

.then()处理程序运行之前执行.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

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

异步结果的解决方案是“在它们被呈现的回调中使用它们”,因为这是您知道它们何时存在的时间的唯一位置。

请记住,在异步代码中,所有$http.get()操作都会启动http请求,然后在后台运行。 其余的Javascript继续运行,有些时候你的异步请求将完成并调用它们的回调,很久你的代码完成执行。


It's a matter of timing. Your .then() handler is called LATER because it represent the completion of all your asynchronous operations. Whereas, your:

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

is executed before your .then() handler has even run so this.listGotten has not yet been set. Your arrow functions are working as expected - this is not an issue related to that.

If you put some console.log() statements into your code to see the actual timing of things like this:

  $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

Then, you will see this output:

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

So, you can see that your .then() handler is called after your other console.log() executes.

The solution for asynchronous results is to "use them in the callback where they are presented" because that's the ONLY place you know the timing for when they exist.

Remember in asynchronous code, all your $http.get() operations just initiate the http requests and then they run in the background. The rest of your Javascript continues to run and some time LATER your asynchronous requests will finish and call their callbacks, long after the rest of your code has finished executing.

2016-07-16

相关文章

更多

最新问答

更多
  • css在元素之前中断列而不破坏包装器(css break column before element without breaking the wrapper)
  • 如何在Xamarin共享项目中使用自定义渲染器(How to use Custom Renderer in Xamarin Shared Project)
  • 如何为特定表中的特定字段设置唯一?(How to set unique for specific field from specific table?)
  • Google SDK iOS - sign()方法完成处理程序(Google SDK iOS - sign() method completion handler)
  • 在具有接口{}值的地图上实现String()(Implement String() on a map with interface{} values)
  • 检查数据库中是否已存在用户名(Check if username already exist in DB)
  • 使用javascript进行ajax调用时阻止用户交互(Block user interaction while doing ajax call using javascript)
  • 什么'if(err)'在Javascript中精确测试?(What does 'if (err)' tests precisely in Javascript?)
  • jQuery mouseleave无法正常工作(jQuery mouseleave not working)
  • 寻求使用的一些说明(Seeking some clarification on use of )
  • 将数组传递给注释的语法(syntax for passing array to annotation)
  • 用于从两个日期范围之间的文件中提取数据的Shell脚本(Shell script to extract data from file between two date ranges)
  • 元素隐藏但父()没有(Element hides but parent() not)
  • 如何使用Google App Engine Java平台开发web ui(How to develop web ui with Google App Engine Java platform)
  • 对于OWL A级;(For an OWL class A; Getting all properties that A is their domain)
  • Excel VBA公式格式问题(Excel VBA Formula Format Issue)
  • ORA - 02287序列号不允许在这里(ORA - 02287 sequence number not allowed here)
  • Github拉忽略特定文件(Github Pull Ignore Specific File)
  • SQL CONVERT函数在SQL Server中工作但不在应用程序中(SQL CONVERT function working in SQL Server but not in application)
  • backbone.js适用于大型应用程序(backbone.js for large applications)
  • 防止程序关闭(Preventing program from closing)
  • 生成不带图像的heightMap(Generating a heightMap without an Image)
  • Bootstrap - 如何将包含文本的div居中?(Bootstrap - How to center div that has text inside it?)
  • Android - 片段findViewById()总是null?(Android - Fragment findViewById() always null?)
  • 确定CSS中的高度(Figuring out heights in CSS)
  • 使用__autoload包含类和使用命名空间(Use __autoload to include class and use namespace)
  • setTimeout()不允许我传递文本值[重复](setTimeout() doesn't allow me to pass text values [duplicate])
  • 在NSUserDefault中恢复值(Restoring value in NSUserDefault)
  • 知道如何将这种下沉的悬停效果添加到图像/链接吗?(Any idea how to add this sinking hover effect to an image/link?)
  • 在XIB中淡入/淡出UISegmentedControl(fade in/fade out UISegmentedControl in XIB)