Угловой и RxJS/switchMap

Здравствуйте, я новичок в 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.info(x)
  })
}

Числа отображаются независимо друг от друга

Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
Promise v/s Observable в Angular
Promise v/s Observable в Angular
В системах Push производитель определяет, когда отправить данные потребителю. Потребитель не знает, когда он получит эти данные.
Подсказка RxJS [filter, skipWhile]
Подсказка RxJS [filter, skipWhile]
Эта подсказка описывает разницу между операторами filter и skipWhile из библиотеки RxJS .
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
1
0
532
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Хотя вы хотите учиться, я думаю, вы должны учиться с самого начала, используя передовой опыт.

И это означает, что вы можете сделать это очень просто без 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.info(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>

Спасибо, но я искал пример, чтобы узнать кое-что о switchMap. Может быть, мой пример бесполезен, но может быть полезен для понимания

szarancza ze spizu 27.05.2019 11:58

Вместо этого попробуйте использовать этот пример: у вас есть наблюдаемый объект, содержащий идентификатор пользователя, и вам нужно получить имя этого пользователя (которое хранится в другом наблюдаемом объекте, содержащем массив { id: number, name: string }.

user4676340 27.05.2019 12:09

Итак, когда мне следует использовать switchMap?

szarancza ze spizu 27.05.2019 13:40

@szaranczazespizu switchMap используется для замены потока другим и отмены любой предыдущей подписки. Это очень полезно для таких вещей, как мгновенное исследование, автозаполнение и т. д.

user4676340 27.05.2019 13:41

@szaranczazespizu, конечно, я отредактировал свой пост. Если у вас есть вопросы по этому поводу, не стесняйтесь спрашивать меня.

user4676340 27.05.2019 14:07

Я нашел простое решение, используя switchMap. При каждом щелчке перезапускайте наблюдаемый счетчик и берите столько предметов, сколько хотите.

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

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

Другие вопросы по теме

Похожие вопросы

Поймать текст сообщения об ошибке в методе подписки rxjs в Angular
TypeError: невозможно прочитать свойство «канал» неопределенного в Redux-Observable
В операторе сканирования Rxjs можно ли удалить элемент из внутреннего накопителя, созданного оператором сканирования?
В Rxjs это анти-шаблон, если вы добавляете значение в массив, а затем сразу после этого испускаете этот массив как наблюдаемый?
Почему набор переменных в области внешней подписки изменяется при изменении внутренних подписок
Angular: выполнение задания при загрузке данных http с использованием HttpClient, Observable и асинхронного канала
Как заставить rxjs дроссель с Темой работать правильно?
Как связать несколько зависимых подписок с помощью операторов и преобразований rxjs?
Карта Rxjs и массив фильтров. Возвращает один объект вместо массива из одного?
Ошибка в новейших rxjs во время компиляции angular