角度和RxJS / switchMap

时间:2019-05-27 09:38:21

标签: angular

你好,我是RxJS的新手,我只是想了解操作员。我想在单击按钮后的一秒钟时间间隔内在控制台中显示接下来的6个数字。我想在下次使用switchMap单击之后重置该计数器。

我一直在尝试使用switchMap,但是计数器没有重置。

obsSwitchMap: Observable<any>;

this.obsSwitchMap = of(null).pipe(
  switchMap(x => from([1, 2, 3]).pipe(
    concatMap(item => of(item).pipe(delay(300)))
    )
  )  
)

onSwitchMapBtnClick() {
  this.obsSwitchMap.subscribe(x => {
    console.log(x)
  })
}

数字彼此独立显示

2 个答案:

答案 0 :(得分:0)

尽管您想学习,但我认为您应该从一开始就学习最佳实践。

这意味着您可以在没有switchMap的情况下非常简单地完成此操作:

const newInterval = () => rxjs.timer(0, 1000).pipe(
  rxjs.operators.map(nb => new Array(6).fill(nb).map((v, i) => v + i + 1))
);

let subscription;

function resetTimer() {
  subscription && subscription.unsubscribe();
  subscription = newInterval().subscribe(v => console.log(v));
}

resetTimer();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.2/rxjs.umd.js"></script>

<button onclick="resetTimer()">Reset timer</button>

编辑

这是一个switchMap示例:

const horsemen = [
  { id: 1, name: 'Death' },
  { id: 2, name: 'Famine' },
  { id: 3, name: 'War' },
  { id: 4, name: 'Conquest' },
];

// Fake HTTP call of 1 second
function getHorseman(id) {
  return rxjs
    .of(horsemen.find(h => h.id === id))
    .pipe(rxjs.operators.delay(1000));
}

const query = document.querySelector('input');
const result = document.querySelector('div.result');

// Listen to input
rxjs.fromEvent(query, 'input')
  .pipe(
    rxjs.operators.map(event => +event.target.value), // Get ID
    rxjs.operators.switchMap(id => getHorseman(id)) // Get Horseman
  ).subscribe(horseman => {
    let content;
    if (horseman) content = `Horseman = ${horseman.name}`;
    else content = `Horseman unknown`;
    result.innerText = content;
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.2/rxjs.umd.js"></script>

<input type="text" placeholder="Input an ID here (1-4)">

<div class="result"></div>

答案 1 :(得分:0)

我找到了使用switchMap的简单解决方案。每次单击时,重新启动可观察的计数器并获取所需的项目数。

const btn = document.querySelector('button');

fromEvent(btn, 'click').pipe(
    switchMap((item => interval(1000).pipe(take(6)))),
).subscribe(console.log)