“减少”和“扫描”之间有什么区别

时间:2017-07-27 12:26:46

标签: javascript rxjs

我正在研究RXJS并坚持这个问题:运算符“reduce”和“scan”的相同代码以不同的方式工作,但我认为必须返回相同的结果。 以下示例。 请帮忙。

const txtElement1 = document.getElementById('txt1');
const txtElement2 = document.getElementById('txt2');
const txtElement3 = document.getElementById('txt3');

// function return Observable
function get(array, initValue) {
  return Rx.Observable.create(observer => {
    let timer = initValue;

    array.forEach(item => {
      setTimeout(() => observer.next(item), timer);
      timer += 1000;
    });
  });
}

// 1) don't work with "reduce"
var stream1$ = get(['John', 'Ann', 'Bob'])
  .reduce(function(acc, x) {
    return acc + ` ${x}`;
  }, 'first - ');

stream1$.subscribe(text => txtElement1.innerHTML = text);

// 2)  the same code, but with "scan" - working
var stream2$ = get(['John', 'Ann', 'Bob'])
  .scan(function(acc, x) {
    return acc + ` ${x}`;
  }, 'second - ');

stream2$.subscribe(text => txtElement2.innerHTML = text);

// 3)  and the simple Observable with "reduce" - working
var stream3$ = Rx.Observable.from(['John', 'Ann', 'Bob'])
  .reduce(function(acc, x) {
    return acc + ` ${x}`;
  }, 'third - ');

stream3$.subscribe(text => txtElement3.innerHTML = text);

3 个答案:

答案 0 :(得分:9)

根据RxJS文档,

  

扫描

     

将一个函数依次应用于Observable发出的每个项目,   和 发射每个连续的值

enter image description here

  

减少

     

将一个函数依次应用于Observable发出的每个项目,   并 发出最终值

enter image description here

示例代码

扫描

var source = Rx.Observable.range(1, 3)
.scan(
    function (acc, x) {
        return acc + x;
    });

var subscription = source.subscribe(
    function (x) { console.log('Next: ' + x); },
    function (err) { console.log('Error: ' + err); },
    function () { console.log('Completed'); });

对于Observable发出的每个值,scan都会依次发出相应的输出,因此Output将有3个值,范围为1到3,如下所示:

Output
Next: 1
Next: 3
Next: 6
Completed

减少

var source = Rx.Observable.range(1, 3)
    .reduce(function (acc, x) {
        return acc * x;
    }, 1)

var subscription = source.subscribe(
    function (x) { console.log('Next: ' + x); },
    function (err) { console.log('Error: ' + err); },
    function () { console.log('Completed'); });

Reduce函数将值从可观察值减小为单个值(最终结果)并发出。所以输出如下,

Next: 6
Completed

答案 1 :(得分:1)

enter image description here

Rx.scan是连续的,而reduce不是连续的。

答案 2 :(得分:0)

几乎相同,但是每次扫描都会发出扫描。而减少只是发出最终结果。当我想实际查看reduce在做什么时,我喜欢扫描。所以有时我。使用减少,我无法想象减少实际上在做什么。在这种情况下,我简单地换出reduce进行扫描,因为它将在每次迭代中发出。这样,我可以在日志语句中查看每次迭代的结果。