Une brève introduction à Rxjs
RxJS est l'abréviation de Reactive Extensions for JavaScript. Il s'agit d'une bibliothèque de programmation réactive basée sur un flux de données observable.
Il est basé sur 订阅-发布模式
et mis 观察者模式
en 迭代器
œuvre.
programmation réactive
La programmation réactive est un paradigme de programmation orienté vers le flux de données et la propagation des changements. Cela signifie que les flux de données statiques ou dynamiques peuvent être facilement exprimés dans des langages de programmation et que le modèle informatique associé propagera automatiquement les valeurs changeantes à travers le flux de données. - Encyclopédie Baidu…
S'abonner-Publier
Le bus dans le projet…
Itérateur
Toutes les méthodes itératrices doivent avoir une next
méthode, next renvoie {value: '', done: 'false || true'}
.
D'un autre côté, tout objet de données qui implémente l'interface de méthode suivante peut être appelé un itérateur.
const arr = [1, 2, 3]
const iterator = arr[Symbol.iterator]()
iterator.next() // {value: 1, done: false}
iterator.next() // {value: 2, done: false}
iterator.next() // {value: 3, done: false}
iterator.next() // {value: 3, done: true}
Idée de base
- Observable (objet observable)
- Observateur
- abonné
- Sujet (objet spécial d'Observable, hérité d'Observable)
- opérateurs (opérateurs internes)
Observable
Les objets observables fournissent trois méthodes
-
next
renvoie une valeur que les observateurs peuvent recevoir -
l'erreur
publie un signal anormal -
complate
publie un signal de fin de traitement
Observateur
Observer, prend en charge trois rappels
- next
gère la valeur publiée par l'observateur - l'erreur
gère les exceptions publiées par les observateurs - complate
gère le signal indiquant que l'observateur publie l'achèvement
abonné
abonnement. Abonnez-vous à l'observateur pour observer ce qui est observé...
Sujet
Une implémentation observable spéciale qui peut agir à la fois comme observé et comme observateur.
Parce que lorsqu'un Observable est abonné, chaque abonné fonctionnera indépendamment.
Le sujet s'apparente davantage à un véritable mainteneur de la gestion des abonnements, il collecte tous les abonnés et les envoie de manière uniforme. un peu similaire au domaddEventListener
les opérateurs
Certaines méthodes et outils à l'intérieur de rxjs pour manipuler le volume de données, tels que la création, la fusion, le filtrage, la conversion, etc.
rxjs paraîtra plus puissant lorsqu'il sera combiné avec certaines opérations...
quelques exemples simples
// 使用create创建一个 observable
const source = rxjs.Observable.create(observable => {
observable.next(1)
})
// 订阅
source.subscribe(v => console.log(v))
// 1
Attendez une minute... Si le code ci-dessus est écrit en utilisant Promise...
const promise = function () {
return new Promise(resolve => resolve(1))
}
promise.then(v => console.log(v))
// 1
// 看着差不多是不是...
Mais le problème est justement que Promise ne peut revenir qu'une seule fois et c'est tout.
const source = rxjs.Observable.create(observable => {
observable.next(1)
observable.next(2)
})
// 订阅
source.subscribe(v => console.log(v))
// 1
// 2
Et pour le traitement après échec, si la promesse échoue et se termine, vous devez l'appeler activement.
getData () {
} // ....
getData().catch(_ => {
getData() // ...
})
// rxjs
const {
interval, throwError, of } = rxjs
const {
mergeMap, retry } = rxjs.operators
// interval 的意思是在指定时间给出一个累加的数字
const source = interval(1000).pipe(mergeMap(val => {
if (val > 5) {
return throwError('大于5了')
}
return of (val + 1)
}), retry(2)) // 这里大于5后会抛出异常,但是又 retry 了2次
source.subscribe(v => console.log(v))
// 输出 3遍 1 - 6,然后抛出异常
Par conséquent, les promesses ne sont pas particulièrement parfaites pour gérer les problèmes asynchrones.
Pour les rappels de error
AND dans les observateurscomplate
:
const source = rxjs.Observable.create(observable => {
observable.next(1)
observable.next(2)
observable.complete()
})
source.subscribe({
next (v) {
// ...
},
error () {
// 处理错误情况...
},
complete () {
// 完成的情况...
}
})
Dans certains scénarios, il est souvent nécessaire de combiner deux interfaces de données 视图层
. Évidemment, la couche de vue n'est pas adaptée à la combinaison de données. Dans ce cas :
const a = rxjs.of({
a: 1})
const b = rxjs.of({
b: 2})
// 将数据流 a 与 b 组合在一起
const c =rxjs.combineLatest(a, b).pipe(rxjs.operators.map(([a, b]) => {
return {
...a, ...b}
}))
c.subscribe(v => console.log(v))
// {a: 1, b: 2}
Scènes filtrées :
const {
interval } = rxjs
const {
filter } = rxjs.operators
// 过滤可以整除2的数据
const source = interval(1000).pipe(filter(val => val % 2 === 0))
source.subscribe(v => console.log(v))
// 0 2 4 6 8...
Il existe d'autres opérateurs
- d'abord
- dernier
- prendre
- retard
- intervalle de temps
Il y en a tellement que je ne vais pas tous les énumérer, mais il y en a environ 100 ?
Les détails peuvent être trouvés ici https://rxjs.dev/guide/operators
analyse de scène
Un exemple particulièrement approprié, Trello.
Pour les données affichées dans le panneau Trello, vous pouvez réfléchir à la manière dont ils planifient et gèrent le flux de données.
- Conditions de traitement ou de filtrage des commandes de cartes
- Combinaison de données des cartes dans la liste des tâches (contenu de la tâche, étiquettes, personnel associé, etc.)
- Fusionner le traitement des anciennes données et des nouvelles données
Ce processus peut être inversé :
// 假如数据组合完毕了,只需要将数据单独过滤然后再排序
const result = source.map(filter).map(sort)
// 假如新老数据已经合并完毕
const source = rxjs.combineLatest(task, label, users).pipe(map (...a) => {
// 一堆合并操作
}) //组合数据
const task = rxjs.merge(oldtask, newtask) // 新旧的数据流合并到一起,对于下一层无感知是新还是旧
// label
// users
La couche suivante de ces données n'a aucune connaissance des données de la couche supérieure. Elle ne se soucie pas de savoir si elles sont nouvelles ou anciennes. Si elles sont fusionnées ou non, il leur suffit de descendre dans le flux de données, et finalement elles atteint le result
calque de vue, il suffit de le rendre directement.
À propos du planificateur
Il est équivalent au planificateur de rxjs et peut modifier le comportement temporel interne de rx.
planificateur | But |
---|---|
null |
Si aucun planificateur n'est transmis, les notifications seront envoyées de manière récursive et synchrone. Utilisé pour les opérations chronométrées ou les opérations récursives de queue. |
Rx.Scheduler.queue |
Planification de file d'attente (planificateur de trampoline) dans le cadre d'événement en cours. Utilisé pour les opérations itératives. |
Rx.Scheduler.asap |
Planification de file d'attente de microtâches, qui utilise le mécanisme de transfert le plus rapide disponible, tel que process.nextTick() MessageChannel de Node.js ou Web Worker ou setTimeout ou autres. Utilisé pour les transformations asynchrones. |
Rx.Scheduler.async |
setInterval Planifiez en utilisant . Pour les opérateurs basés sur le temps. |