Чтобы пропустить каждое испускаемое значение через последовательность операторов, мы вызываем метод pipe. Обязательно вставьте его перед subscribe.
Теперь укажем операторы. Сначала давайте преобразуем значения.
Какие операторы мы используем для преобразования значений? Если вы сказали map, то вы правы. Мы будем использовать map для преобразования испускаемого значения, умножая его на 2.
Метод observable pipe принимает любое количество операторов, разделенных запятыми.
Добавим второй оператор map, чтобы снова преобразовать значение, вычитая 10. Теперь мы видим преобразованные элементы в консоли.
from ([20, 15, 10, 5]).pipe(
map(item => item * 2),
map(item => item -10)
).subscribe({
next: (item) => console.log(`resulting item.. ${item}` ),
error: (err) => console.log(`error occoured ${err}`),
complete: () => console.log('Completed')
})
Чтобы также вывести в журнал первоначально пропущенный элемент, добавим тап в начале последовательности.
Теперь мы видим первоначально пропущенный элемент и преобразованный элемент.
Обратите внимание на 0, который мы видим в результате.
from ([20, 15, 10, 5]).pipe(
tap(item => console.log(`emitted item ... ${item}`)),
map(item => item * 2),
map(item => item -10),
map(item => {
if(item === 0){
throw new Error ('Zero detected');
}
return item;
})
).subscribe({
next: (item) => console.log(`resulting item.. ${item}` ),
error: (err) => console.log(`error occoured ${err}`),
complete: () => console.log('Completed')
})
Давайте попробуем обработать ошибку и добавим проверку на 0. Для обработки ошибок мы будем использовать оператор map. Оператор map принимает элемент. Если мы хотим выполнить несколько строк, нам нужно тело функции, определенное фигурными скобками. Это превращает нашу однострочную стрелочную функцию в многострочную стрелочную функцию.
Мы будем использовать оператор if для проверки значения 0
и выбросим ошибку, если обнаружим 0
. В противном случае мы возвращаем элемент.
Обратите внимание, что в этом случае нам необходимо ключевое слово
return
. Однострочная стрелочная функция имеет подразумеваемый возврат.
Когда мы используем многострочную стрелочную функцию, нам нужен явный оператор возврата.
Возьмем
Наконец, давайте добавим take и возьмем только три элемента. Мы больше не видим нашей ошибки. Мы берем первые три элемента и завершаем выполнение до того, как будет выдан элемент с ошибкой.
from ([20, 15, 10, 5]).pipe(
tap(item => console.log(`emitted item ... ${item}`)),
map(item => item * 2),
map(item => item -10),
map(item => {
if(item === 0){
throw new Error ('Zero detected');
}
return item;
}),
take(3)
).subscribe({
next: (item) => console.log(`resulting item.. ${item}` ),
error: (err) => console.log(`error occoured ${err}`),
complete: () => console.log('Completed')
})
Файл app.component.ts
import { Component, VERSION, OnInit } from '@angular/core';
import {of, from, map, tap, take} from 'rxjs'
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
name = 'Angular ' + VERSION.major;
ngOnInit(){
from ([20, 15, 10, 5]).pipe(
tap(item => console.log(`emitted item ... ${item}`)),
map(item => item * 2),
map(item => item -10),
map(item => {
if(item === 0){
throw new Error ('Zero detected');
}
return item;
}),
take(3)
).subscribe({
next: (item) => console.log(`resulting item.. ${item}` ),
error: (err) => console.log(`error occoured ${err}`),
complete: () => console.log('Completed')
})
}
}
Внутреннее устройство оператора карты
import { Observable } from 'rxjs';
export function map(fn) {
// function
return (
input // takes an input Observable
) =>
new Observable((observer) => {
// creates an output Observable
return input.subscriber({
// subscribes to the input Observable
next: (value) => observer.next(fn(value)), // transform item using provided function and emits item
error: (err) => observer.error(err), // emits error notification
complete: () => observer.complete(), // emits complete notification
});
});
}