我遇到了这种奇怪的行为或我不知道的事情。 对于以下内容,
of(1).pipe(
filter(_ => false),
startWith('hello')
).susbcribe(val => console.log(val));
以上代码在控制台中输出hello
。
我期望的是,由于filter仅允许成功的条件沿操作员链下降,因此它如何通过startWith()输出hello?这是预期的行为吗?
答案 0 :(得分:2)
startWith
在您过滤内容之后发生。
of(1).pipe( // will yield (1)
filter(_ => false), // will yield ()
startWith('hello') // will yield ('hello')
).susbcribe(val => console.log(val));
因此,由1
组成的流经过过滤以使任何内容都不通过本身就是一件事。然后用startWith
运算符对该东西进行“修饰”,使其产生初始的hello
。
这是您订阅的新信息流!
这确实是预期的行为。
在startWith
参数中将filter
置于pipe(...)
上方,您将看到这种变化:
of(1).pipe( // will yield (1)
startWith('hello'), // will yield ('hello', 1)
filter(_ => false) // will yield ()
).susbcribe(val => console.log(val));
要解决评论部分中的问题,可以将pipe
链视为nested calls
。例如,使用伪代码:
A.pipe(B, C, D)
...等价于:
D(C(B(A)))
因此,以下内容:
of(1).pipe( // expression A
filter(_ => false), // expression B
startWith('hello') // expression C
).susbcribe(val => console.log(val));
...将翻译为:
startWith( // expression C
filter( // expression B
of(1), // expression A
_ => false
),
'hello'
).susbcribe(val => console.log(val))
或者,以一种更“必要”的方式:
const one = of(1);
const filtered = filter(one, _ => false);
const greeted = startWith(filtered, 'hello');
greeted.subscribe(val => console.log(val));
然后很明显,过滤器不会不会影响到运营商的下游!
答案 1 :(得分:0)
startWith()运算符仅调用concat()运算符。起始参数为第一个可观察值,外部参数为第二个。
concat()
运算符为从 left 到 right 的每个可观察值发出值。 first 可观察对象必须发出所有值,并在发出 next 可观察对象之前完成。
例如;
concat(of('a','b'), of('1', '2')
.subscribe(val => console.log(val));
// prints 'a', 'b', '1', '2'
因此,我们可以重写示例以使用concat()
并生成相同的结果,这基本上就是startWith()
在内部所做的事情。
concat(of('hello'), of(1).pipe(filter(_ => false))
.subscribe(val => console.log(val));
// prints "hello"
因此startWith()
对可观察对象的序列进行重新排序,以便首先发出值,但是由于它是一个运算符,因此只能 lift < / em>外部可观察到的。在pipe()
之后 startWith()
中放置在concat()
之后的任何运算符都将应用于可观察对象。