Javascript 为什么for循环中的观测值工作方式不同?

Javascript 为什么for循环中的观测值工作方式不同?,javascript,angular,typescript,rxjs,observable,Javascript,Angular,Typescript,Rxjs,Observable,我现在正在学习Angular 6,现在面临着一个我无法理解的可观察问题 请看下面我的代码 export class ShoppingCartComponent implements OnInit { cart$; products = {}; constructor(private shoppingCartService : ShoppingCartService, public productService : ProductService) { var subscri

我现在正在学习Angular 6,现在面临着一个我无法理解的可观察问题

请看下面我的代码

export class ShoppingCartComponent implements OnInit {
  cart$;
  products = {};
  constructor(private shoppingCartService : ShoppingCartService, 
  public productService : ProductService) { 
  var subscription = from(this.shoppingCartService.getCart());
  subscription.subscribe(cart => cart.subscribe(shoppingcart => {
     var items = shoppingcart.items;
     console.log(shoppingcart.items);
     for(let key in items){
         console.log(key);
         this.productService.get(key).valueChanges().subscribe(product=>{
            this.products[key] = product['title'];
            console.log(product);
            console.log(this.products);
            //console.log(key);
         });
     }
  }));
 }
}
订阅中的购物车是可见的

export class ShoppingCart {
    constructor(public items: ShoppingCartItem[]){ }

    get productIds(){
      return Object.keys(this.items);
    }

    get totalItemsCount(){
      let count = 0;
      for (let productId in this.items)
        count += this.items[productId].quantity;
      return count;
    }
}

export interface ShoppingCartItem{
    product : Product;
    quantity : number;
}
这个angular应用程序从firebase数据库获取shoppingcart,如果我运行它,我会得到奇怪的结果。请看截图。Products对象似乎被最后一个键(花椰菜)覆盖。

但是,如果我切换回注释“console.log(key)”。效果很好,如下面的屏幕截图所示

这是因为for循环中的let变量吗

若将let关键字替换为var,则products对象仅具有菜花,而不考虑console.log(键)

请让我知道

谢谢

for(var value of ['foo', 'bar', 'baz']) {
  setTimeout(() => console.log(value), 0);
}
// baz
// baz
// baz

console.log(value);
// baz
由于setTimeout是在for of循环外部调用的,因此每次都使用相同的
存在于循环外部(块范围)

let
const
变量

使用let关键字,babel将在以下位置传输:

var _arr = ['foo', 'bar', 'baz'];

var _loop = function _loop() {
      var value = _arr[_i];
      setTimeout(function () {
            return console.log(value);
      }, 0);
};

for (var _i = 0; _i < _arr.length; _i++) {
      _loop();
}
var\u arr=['foo','bar','baz'];
var _loop=函数_loop(){
var值=_arr[_i];
setTimeout(函数(){
返回console.log(值);
}, 0);
};
对于(变量i=0;\u i<\u arr.length;\u i++){
_loop();
}

在for of循环的每次迭代中,都会在
\u loop

中创建新的

let关键字用于防止此类问题(包括setTimeout或observeable.subscribe等异步情况)。你能在StackBlitz上建立一个简单的例子来说明这个问题吗?你试过const关键字了吗?