【问题标题】:Pass more values to subscribe function of an observables传递更多的值来订阅 observables 的函数
【发布时间】:2017-04-26 04:43:17
【问题描述】:

我想使用返回 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
        });
    }

【问题讨论】:

    标签: javascript typescript observable


    【解决方案1】:

    从 ES6 开始,您可以通过将 var i = 替换为 let i = 轻松解决此问题。这样,您将获得一个具有 block 范围的变量,因此您在循环的每次迭代中都会获得一个不同的变量实例。

    当您不支持 let 时,原始答案也有效:

    你可以用一个简单的函数来解决这个问题,你可以绑定一个额外的参数:

    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 提供,另一个由调用者提供。

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

    【讨论】:

    • 你能解释一下 bind 到底在做什么吗?
    • 添加说明。
    • 赞成比文档更清晰的解释:)
    【解决方案2】:

    另一种选择可能是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

    【讨论】:

      猜你喜欢
      • 2017-10-07
      • 2021-07-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多