简体   繁体   English

理解 RXJS 可观察输出的问题

[英]Issue with understanding RXJS Observable Output

I'm fairly new to rxjs and trying to learn.我对 rxjs 还很陌生,正在努力学习。

I was reading through this medium article and trying to understand this RXJS output:我正在阅读这篇中等文章并试图理解这个 RXJS 输出:

import {Observable} from 'rxjs-es';
let output = Observable.interval(500)
             .map(i => [1,2,3,4,5,6][i]);

let result = output.map(num1 => num1)
    .filter(num1 => num1 > 4)
    .reduce((num1, num2) => num1 + num2);

result.subscribe(number => console.log(number));

Output: 27输出:27

I don't understand how the output turned out to be 27 and how that reduce is working (and what are those two arguments for the reducer).我不明白输出结果是 27 以及 reduce 是如何工作的(以及 reducer 的这两个参数是什么)。

Can someone enlighten me what's happening?有人可以启发我这是怎么回事吗? (I've tried to run it on codesandbox however it's throwing an error when I run this code) (我尝试在代码和框上运行它,但是当我运行此代码时它会抛出错误)

Understanding Filter and Reduce Operators了解Filter和化Reduce运算符

As others have mentioned in the comments, the article you refer to is using an older version of rxjs that has a different syntax.正如其他人在评论中提到的那样,您引用的文章使用的是具有不同语法的旧版本 rxjs。 For this example I'll use the newer syntax that started in version 6.对于此示例,我将使用从版本 6 开始的较新语法。

In rxjs, there are various operators available to transform the values emitted through a stream.在 rxjs 中,有多种运算符可用于转换通过流发出的值。 Typically these are imported like:通常这些是导入的:

import { filter, reduce } from 'rxjs/operators';

There are also many generator functions available to create a stream of values.还有许多生成器函数可用于创建值流。 interval is one of these functions that will create a stream that emits sequential integers every n milliseconds. interval是这些函数之一,它将创建一个每n毫秒发出一个连续整数的流。 Imported like:进口如:

import { interval } from 'rxjs';

Let's create a simple stream:让我们创建一个简单的流:

number$ = interval(1000); // emit number every 1 second
// output: 0, 1, 2, 3, 4, 5...

We can apply operators to this stream to transform the emissions:我们可以将运算符应用于此流以转换排放:

The usage of filter is pretty simple. filter的使用非常简单。 It simply emits values that pass the given truth test (exactly like the Array.filter() method).它只是发出通过给定真值测试的值(与Array.filter()方法完全一样)。

numbersLessThan4$ = numbers$.pipe(
    filter(number => number < 4)
);
// output: 0, 1, 2, 3

The reduce operator is a bit more complex and behaves just like the Array.reduce() method. reduce运算符稍微复杂一些,其行为就像Array.reduce()方法。 A function is applied to each emitted value and is able store a value that can be referenced when the next emission is evaluated.一个函数被应用于每个发出的值,并且能够存储一个值,在评估下一次发出时可以引用该值。

reduce takes two parameters. reduce需要两个参数。 The first is a function that receives the current emission ( cur ) and the previous accumulated result ( acc ) and returns a new accumulated value.第一个是接收当前发射 ( cur ) 和先前累积结果 ( acc ) 并返回新累积值的函数。 The second is an initial value for acc .第二个是acc的初始值。

example:例子:

sumOfNumbers$ = numbers$.pipe(
    reduce((acc, cur) => acc + cur, 0)
);

So, let's look what reduce does when numbers$ emits the first 3 numbers:所以,让我们看看当numbers$发出前 3 个数字时reduce做了什么:

  • 0 0
    • cur receives the current emission value 0 cur接收当前的发射值0
    • acc starts with the provided default 0 acc以提供的默认值0开头
    • the expression acc + cur returns 0表达式acc + cur返回0
  • 1 1
    • cur receives the current emission value 1 cur接收当前的发射值1
    • acc receives the previously returned value 0 acc接收先前返回的值0
    • the expression acc + cur returns 1表达式acc + cur返回1
  • 2 2
    • cur receives the current emission value 2 cur接收当前的发射值2
    • acc receives the previously returned value 1 acc接收先前返回的值1
    • the expression acc + cur returns 3表达式acc + cur返回3

So this is cool.所以这很酷。 We can get quite a lot of logic into a simple line of code.我们可以在一行简单的代码中得到相当多的逻辑。 One important thing about reduce is that it will not emit until the source observable completes.关于reduce一件重要的事情是它在源observable 完成之前不会发出。 Currently, numbers$ never completes ( interval() emits sequential integers indefinitely).目前, numbers$永远不会完成( interval()无限期地发出连续整数)。

We can use the take() operator to complete the stream after a certain number of values are emitted.在发出一定数量的值后,我们可以使用take()运算符来完成流。

Example:例子:

numbers$ = interval(1000).pipe(take(5)); // completes after 5 emissions

sumOfNumbers$ = numbers$.pipe(
    // receives 5 values (0, 1, 2, 3, 4) and performs the logic described above.
    reduce((acc, cur) => acc + cur, 0) 
);
// output: 10

Multiple operators can be used to transform the emissions.可以使用多个运算符来转换排放。 Simply provide multiple inside the pipe() :只需在pipe()内提供多个:

sumOfNumbersLessThan4$ = numbers$.pipe(
    filter(number => number < 4),
    reduce((acc, cur) => acc + cur, 0) 
);
// output: 6

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM