English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
前言
RxJs提供的是核心的Observable对象,它是一个使用可观察数据序列实现组合异步和事件编程的框架。
与这个非常类似的异步编程模型是Promise,Promise是基于状态变化的异步模型,一旦从等待状态进入成功或失败状态便不能再次修改,当状态变化时订阅者只能获得一个值;而Observable是基于序列的异步编程模型,随着序列的变化,订阅者可以持续不断地获取新的值。此外,Promise只提供回话机制,并没有更多的操作来支持对结果的复杂处理,而Observable提供了各种各样的操作符,用于处理运算结果,以满足复杂的应用逻辑。
在实际编程中,我们主要与三个对象打交道:Observable、observer、Subscription:
以一个元素的click事件为例看看如何使用Observable:
var clickStream = new Rx.Observable(observer => { var handle = evt => observer.next(evt); element.addEventListener('click', handle); return () => element.removeEventListener('click', handle); }); subscription = clickStream.subscribe(evt => { console.log('onNext: ')} + evt.id); }, err => { console.error('onError'); }, () => { console.log('onComplete'); }); setTimeout(() => { subscription.unsubscribe(); }, 1000);
Wenn jedes Ereignis so verpackt werden muss, ist das doch sehr lästig, daher bietet RxJs uns eine bequeme Funktion: Observable.fromEvent, um die Ereignisse besser zu verknüpfen.
Gängige Verknüpfungsoptionen:concat, merge, combineLates und andere
Projektionsoperationen:map, flatMap, flatMap ist besonders zu beachten
Filtern:filter, distinctUltilChanges
Kategorien der Operatoren:Operators by Categories
Fehlerbehandlung:catch, retry, finally
Druck abbauen:debounce, throttle, sample, pausable
Reduzieren:buffer, bufferWithCount, bufferWithTime
Um die Operatoren von Observable zu beherrschen, muss man zunächst lernen, Sequenzdiagramme zu verstehen:
Die Pfeile stellen die mit der Zeit variierenden Sequenzen dar, z.B. das ständige Klicken auf einen Element, der Kreis stellt den Einfluss der Sequenz auf die Außenwelt dar, wie z.B. das Auslösen eines Ereignisrückrufs bei jedem Klick auf ein Element, die Zahl im Kreis stellt die emittierten Informationen dar, wie z.B. bei jedem Ereignis ausgelöst wird, es gibt einen Ereignisobjekt, das einige Informationen über diese Operation darstellt.
Um Observable flexibel in der Verarbeitung komplexer Logiken zu verwenden, muss man die bereitgestellten Operatoren lernen. Ich teile die Operatoren in zwei Kategorien ein: Einzelsequenzoperationen und komplexe Sequenzoperationen. Einzelsequenzoperationen beziehen sich auf Operationen, die auf eine Sequenz angewendet werden, während komplexe Sequenzoperationen auf die Verarbeitung von zwei oder mehreren Sequenzen hinweisen. Komplexe Sequenzoperationen sind relativ schwer zu verstehen.
Zunächst schauen wir uns eine Operation an, die nur eine Sequenz betrifft, hier als Beispiel die map-Operation:
Die map-Operation führt eine Transformation der von einer Sequenz emittierten Informationen bei jedem Aufruf durch. Wie im obigen Beispiel hat map jeden emittierten Wert mit zehn multipliziert, sodass der abonnierte Wert nach der Abonnierung nicht mehr der ursprüngliche Wert ist123sondern nach der Transformation10 20 30. Durch die Verwendung von Sequenzdiagrammen kann der Observable-Operation einfacher verstanden werden.
Lassen Sie uns einen Beispiel für eine komplexe Sequenzoperation betrachten, hier als Beispiel merge
Der Zweck der Merge-Operation ist es, zwei unabhängige Sequenzen zu einer einzigen Sequenz zu kombinieren. Die ursprüngliche Sequenz1Mit fortschreitender Zeit in10a um 0ms emittiert wird, in2b um 00ms emittiert wird3c um 00ms emittiert wird, und der Abonnent erhält4abc drei Werte innerhalb von 00ms empfangen; die Sequenz2in15d um 0ms emittiert wird25e um 0ms emittiert wird35f um 0ms emittiert, und der Abonnent erhält4def drei Werte innerhalb von 00ms empfangen. Nach dem Merge der neuen Sequenz wird4abcdef innerhalb von 00ms empfangen (Beachtung der Reihenfolge).
Verständnis der gängigen Operatoren:
Observable.range:Emitiert eine Sequenz mit einer bestimmten Anzahl von Werten
Observable.toArray: Wandelt alle emittierten Werte in ein Array um, wenn die Sequenz abgeschlossen ist
Observable.flatMap: Konvertiert Elemente aus dem ursprünglichen Sequenzstrom in einen neuen Sequenzstrom und merge diesen neuen Sequenzstrom an die Position der Elemente im ursprünglichen Sequenzstrom
Observable.startWith: Setzt den ersten Wert der Observable-Sequenz
Observable.combineLatest: Ähnlich wie promiseAll, führt es erst aus, wenn alle Sequenzen Ergebnisse haben
Observable.scan: Fügt Werte aus der Sequenz zusammen, ähnlich wie reduce, das die Werte der gesamten Sequenz zusammenfasst und eine finale Wertemeldung sendet, wenn die Sequenz abgeschlossen ist
Observable.sample: Nimmt eine bestimmte Anzahl von Proben aus einer anhaltenden Sequenz
Observable.merge:Fügt mehrere Sequenzen zu einer zusammen, kann als OR verwendet werden
Observable.timestamp: Gibt die Zeit des Emittens jedes Werts zurück, wenn der Wert emittiert wird
Observable.distinctUntilChanged(compare, selector): selector extrahiert den Schlüssel, der zur Vergleichsoperation verwendet wird, und compare vergleicht zwei Schlüssel
Observable.takeWhile() Beenden Sie das Senden von Daten, wenn der Parameter auf false gesetzt ist
Zusammenfassung
Das ist der gesamte Inhalt dieses Artikels. Ich hoffe, dieser Artikel kann Ihnen bei Ihrem Lernen oder Ihrer Arbeit ein gewisses Maß an Hilfe bringen. Wenn Sie Fragen haben, können Sie Kommentare hinterlassen.