将更多值传递给可观察量的订阅函数

时间:2016-12-11 00:37:53

标签: javascript typescript observable

我想使用返回可观察对象的对象方法转换并替换数组中的所有单词。问题是由于结果是异步的,因此在错误的索引处错误地覆盖了结果的值。如果我有一个同步函数,我可以简单地在for循环中调用该函数。在这种情况下我该怎么做?

 for(let word in this.words){
        var i = Object.keys(this.words).indexOf(word);

        this.convertor.get(this.words[i].value).subscribe( (result) => {
            this.words[i].value = result; //The value of i is incorrect
        });
    }

2 个答案:

答案 0 :(得分:6)

您可以使用将额外参数绑定到的简单函数来解决此问题:

    this.convertor.get(this.words[i].value).subscribe( function (i, result) {
        this.words[i].value = result; 
    }.bind(this, i));

.bind()返回一个(新)函数,它类似于您应用bind的函数,但会预先确定实际调用该函数时的一些内容:

    然后将
  1. this设置为您在第一个参数中传递给bind的内容。与箭头函数相反,老式函数通常根据函数的调用方式获得this值 - 这种行为不是您想要的,因此它是bind的一个受欢迎的特性;

  2. 可以预先修复一些参数。无论你通过bind传递的其他参数都成为该函数的第一个参数的值 - 它们不是由实际调用决定的。在这种情况下,传递 i 的值,因此该函数将获取该值作为其第一个参数,无论以后如何调用它。

  3. 在调用(返回)时传递给函数的任何其他参数都将遵循前面提到的参数。在这种情况下,实际调用将传递 result 的值,因此该函数应该处理两个参数:一个由bind提供,另一个由调用者提供。

  4. 这解决了您的问题,因为您可以将 i 的正确值传递给每个函数,而不会丢失this的值。

答案 1 :(得分:1)

另一种选择可能是forEach,因此您不必跟踪索引并处理例如使用first()清理订阅的情况。

this.words.forEach((word, i) => {
  this.obs$(word)
    .pipe(
      tap(v => (this.words[i].value = v)),
      first()
    )
    .subscribe();
});

https://stackblitz.com/edit/static-iterable-value-from-obs?file=src/app/app.component.ts