首页 > 解决方案 > 为什么将相同的 observable 传递给 concat() 多次以这种方式工作?

问题描述

我在文档上读到:

如果你多次传递 concat 相同的 Observable,它的值流将在每次订阅时“重播”,这意味着你可以重复给定的 Observable 任意多次。如果将同一个 Observable 传递给 concat 1000 次变得乏味,你总是可以使用 repeat。

https://rxjs.dev/api/index/function/concat

我的问题是:为什么它会这样工作?我希望它只返回第一个 observable 的值,然后完成(因为所有其他的也会完成,因为我们指的是同一个 observable)。concat()以这种方式工作将与其他行为一致。

标签: angularrxjsrxjs-observables

解决方案


考虑以下:

// Defining a function
const addTwoNumbers = a => b => () => {
  console.log(`Adding ${a} + ${b}`);
  return a + b;
}

// Defining another function
const increment = addTwoNumbers(1);

// Defining another function
const incFive = increment(5);

// Invoking the final function to get a result
const result = incFive();

// Result is 6
console.log(`Result is ${result}`);


// Invoke 3 more times
[incFive, incFive, incFive].forEach(
  fn => fn()
);

注意我们1 + 5每次调用时是如何运行代码的incFive?如果你运行这段代码,你会看到

Adding 1 + 5
Result is 6
Adding 1 + 5
Adding 1 + 5
Adding 1 + 5

函数中的代码总共“运行”了 4 次,即使该函数只定义了一次。


这就是 observables 的工作方式!subscribe说运行 observable,所以如果你订阅 10 次,你运行 observable 10 次。

当然,如果你正在处理一个“热”的 observable,这会有所改变。使用concat重复一个监听按钮舔的可观察对象(例如)没有多大意义。然而,使用concat从服务器请求更新更有意义。

定义一个可观察对象并能够重用它是很好的。上面,“再调用 3 次”下面的行可以重写为:

// Redefine 3 more times
[addTwoNumbers(1)(5),addTwoNumbers(1)(5), addTwoNumbers(1)(5)].forEach(
  fn => fn()
);

但这很麻烦!此外,有时您想在一个地方定义一个函数并在另一个地方完全调用它。到那时你可能不知道如何重新定义它。可观察对象也是如此。


推荐阅读