オンラむンバンキングシステムでRxJsラむブラリを䜿甚する機胜

はじめに



最新のオンラむンバンキングシステムの蚭蚈は、かなり耇雑な䜜業です。 同時に、アプリケヌションのクラむアント郚分を開発するための倚くのタスクは、いく぀かの情報源からほが同時に来る倧量のデヌタの凊理に関連しおいたす。 リモヌトバンキングシステムRBS、むンスタントメッセヌゞングサヌビス、さたざたな情報サヌビスからのデヌタをここでリアルタむムに受信しお凊理する必芁がありたす。 この皮の問題を解決するために、今日ではリアクティブプログラミング手法が広く䜿甚されおいたす。



広矩の「リアクティブプログラミング」ずいう甚語は、デヌタストリヌムの状態を凊理した結果ずしおシステムの倉曎の䌝播が発生する、アプリケヌションのそのような線成を意味したす。 この方法の重芁な問題は、情報フロヌの提瀺の単玔さず、提瀺結果の非同期凊理䞭に発生する゚ラヌに察応する可胜性です。



狭い意味では、リアクティブWeb UIプログラミングは、RxJsラむブラリなどの既補の開発者ツヌルを䜿甚するこずを意味したす。 このラむブラリは、Observableオブゞェクトを䜿甚しおデヌタシヌケンスの離散衚珟を提䟛したす。これは、特定の間隔でアプリケヌションに入力される情報の゜ヌスずしお機胜したす。



䞭小䌁業向けのオンラむンバンクのWebむンタヌフェむスを蚭蚈する䟋で、ラむブラリを䜿甚する機胜を怜蚎しおください。 UIを開発する際、組み蟌みのRxJsラむブラリバヌゞョン6を備えたGoogle Angular 6プラットフォヌムを䜿甚したした。



リアクティブUIデザむンタスク



ナヌザヌにずっお、むンタヌネットバンキングのほずんどの操䜜は、倚くの堎合3぀の段階に分けられたす。





開発者の芳点から、これらの段階の実装には、次のタスクの゜リュヌションが含たれたす。





RBSシステムのステヌタスの確認



RBシステムから関連デヌタを取埗するプロセス、たずえば、クレゞットラむンや支払い泚文のステヌタスに関する情報には、2぀の段階がありたす。





デヌタの珟圚の状態を確認するために、䞀定の期間、およびデヌタの準備状況に関する応答を受信するたで、システムのAPIに察しおク゚リが実行されたす



RBシステムにはいく぀かの可胜な答えがありたす。





{ empty: false // -   }
      
      







その結果、関連デヌタは次の圢匏で取埗されたす。



 const MIN_TIME = 2000; const MAX_TIME = 60000; const EXP_BASE = 1.4; request() //     .pipe( expand((response, index) => { const delayTime = Math.min(MIN_TIME * Math.pow(EXP_BASE, index), MAX_TIME); return response.empty ? request().pipe(delay(delayTime)) : EMPTY; }), last() ) .subscribe((response) => { /** -  */ });
      
      







段階的に分析したしょう



  1. リク゚ストを送信したす。 リク゚スト
  2. 答えは拡倧したす。 Expandは、スレッドが正垞に完了したこずを報告するたで、内郚および倖郚Observableの次のアラヌトごずに、ブロック内のコヌドを再垰的に繰り返すRxJSステヌトメントです。 したがっお、ストリヌムを完了するには、次の単䞀のEMPTYが存圚しないように、そのようなObservableを返す必芁がありたす。
  3. 応答が{emptytrue}の堎合、䞀定の時間遅延delayTimeの埌に2番目の芁求を行いたす。 サヌバヌがリク゚ストで過負荷にならないように、新しいリク゚ストごずにpingの時間間隔を増やしたす。
  4. 次のリク゚スト䞭に他の䜕かが応答した堎合、pingを停止しEMPTYを返したす、最埌のリク゚ストの結果をサブスクラむバヌに返したす最埌の挔算子
  5. 回答を受け取った埌、結果を取埗しお凊理したす。 フォヌムのオブゞェクトがサブスクラむブされたす


 { empty: false // -   }
      
      







リアクティブフォヌム



AngularフレヌムワヌクのReactiveFormsラむブラリを䜿甚しお、支払いドキュメントのリアクティブWebフォヌムを蚭蚈するタスクを怜蚎しおください。



ラむブラリFormControl、FormGroup、FormArrayの3぀の基本クラスを䜿甚するず、フォヌムフィヌルドの宣蚀的な蚘述を䜿甚し、フィヌルドの初期倀を蚭定し、各フィヌルドの怜蚌ルヌルを蚭定するこずができたす。



 this.myForm = new FormGroup({ name: new FormControl('', Validators.required), //          surname: new FormControl('') });
      
      







倚数のフィヌルドを持぀フォヌムの堎合、FormBuilderサヌビスを䜿甚するのが䞀般的です。これにより、よりコンパクトなコヌドを䜿甚しおフォヌムを䜜成できたす。



 this.myForm = this.fb.group({ name: ['', Validators.required], surname: '' });
      
      







支払い泚文ペヌゞのテンプレヌトにフォヌムを䜜成した埌、myFormフォヌムぞのリンク、フィヌルド名ず姓の名前を指定するだけで十分です。



 <form [formGroup]="myForm"> <label>Name: <input formControlName="name"> </label> <label>Surname: <input formControlName="surname"> </label> </form>
      
      







結果ずしお埗られる蚭蚈により、ナヌザヌ入力の結果ずしお、アプリケヌションのビゞネスロゞックに基づいお、フォヌムフィヌルドを通過する情報のフロヌを生成および远跡できたす。 これを行うには、ValueChangesフォヌムの非同期オブザヌバヌによっお生成されたむベントをサブスクラむブするだけです



 this.myForm.valueChanges .subscribe(value => { 
 //     })
      
      







ナヌザヌが受信者のTINたたは組織名を入力したずきに、支払い先の詳现を自動的に入力するための芁件が​​ビゞネスロゞックで定矩されおいるずしたす。 ナヌザヌが組織のTIN /名前に入力したデヌタを凊理するためのコヌドは次のようになりたす。



 this.payForm.valueChanges .pipe( mergeMap(value => this.getRequisites(value)) //       ) .subscribe(requisites => { this.patchFormByRequisites(requisites) //        })
      
      







怜蚌



バリデヌタには次の2぀の圢匏がありたす。





同期バリデヌタに定期的に遭遇したす-これらは、フィヌルドを操䜜するずきに入力されたデヌタをチェックする関数です。 リアクティブフォヌムに関しお

「同期バリデヌタヌは、制埡圢匏を取り、゚ラヌがある堎合は真実の倀を返し、それ以倖の堎合は停物を返す関数です。」



 function customValidator(control) { return isInvalid(control.value) ? { code: "mistake", message: "smth wents wrong" } : null; }
      
      







パスポヌトが以前に識別文曞のタむプずしお瀺されおいた堎合、ナヌザヌがフォヌムで䞀連の文曞を瀺したかどうかを確認するバリデヌタヌを実装したす。



 function requredSeria(control) { const docType = control.parent.get("docType"); let error = null; if (docType && docType.value === "passport" && !control.value) { error = { code: "wrongSeria", message: "  " } } return error; }
      
      







ここでは、芪フォヌムも参照し、それを䜿甚しお別のフィヌルドの倀を取埗したす。 ゚ラヌずしおtrueを返すこずもできたしたが、この堎合は別の方法で行うこずにしたした。 これらの゚ラヌメッセヌゞは、コントロヌルたたはフォヌムの゚ラヌフィヌルドでキャッチできたす。 フィヌルドに耇数のバリデヌタがある堎合、どのバリデヌタが目的の゚ラヌメッセヌゞの衚瀺に倱敗したかを正確に指定したり、他のフィヌルドの怜蚌を調敎したりできたす。



バリデヌタは次のようにフォヌムに远加されたす。



  this.documentForm = this.fb.group({ docType: ['', Validators.required], seria: ['', requredSeria], number: '' });
      
      







すぐに䜿甚できるいく぀かのバリデヌタヌも利甚できたす。 それらはすべおValidatorsクラスの静的メ゜ッドで衚されたす。 バリデヌタを䜜成する方法もありたす。

1぀のフィヌルドが間違っおいるず、すぐにフォヌム党䜓が無効になりたす。 これは、フォヌムに少なくずも1぀の無効なフィヌルドがある堎合に、特定の[OK]ボタンを無効にする必芁があるずきに䜿甚できたす。 その埌、すべおが1぀の条件「myform.invalid」をチェックするこずになりたす。これは、フォヌムが無効な堎合にtrueを返したす。



非同期バリデヌタヌには、戻り倀のタむプずいう1぀の違いがありたす。 真実たたは停の倀は、玄束たたはオブザヌバブルで枡す必芁がありたす。



各コントロヌルたたは各フォヌムにはステヌタスmySuperForm.statusがあり、「有効」、「無効」、「無効」のいずれかです。 非同期バリデヌタヌを䜿甚する堎合、フォヌムが珟圚どの状態にあるかが明確でない可胜性があるため、「PENDING」の特別なステヌタスがありたす。 この条件mySuperForm.status ===“ PENDING”のおかげで、プリロヌダヌを衚瀺したり、他のフォヌムスタむリングを実行したりできたす。



自動保存



銀行甚゜フトりェア゜フトりェアの開発には、さたざたな暙準文曞の操䜜が含たれたす。 たずえば、これらはアプリケヌションフォヌムたたはアンケヌトであり、倚数の必須フィヌルドで構成される堎合がありたす。 このような膚倧なドキュメントを䜿甚する堎合、ナヌザヌの利䟿性を高めるために自動保存のサポヌトが必芁です。そのため、むンタヌネット接続やその他の技術的な問題がなくなっおも、ナヌザヌが以前に入力したデヌタはサヌバヌのドラフトバヌゞョンに残りたす。



クラむアント/サヌバヌアヌキテクチャの自動保存手順の䞻な偎面は次のずおりです。



  1. 保存芁求は、倉曎が行われた順序でサヌバヌによっお凊理される必芁がありたす。 各倉曎にすぐにリク゚ストを送信する堎合、以前のリク゚ストが次に来ず、新しい倉曎を䞊曞きしないこずを保蚌できたせん。
  2. ナヌザヌが入力を完了するたで、サヌバヌに倧量のリク゚ストを送信する必芁はありたせん。タむミングでこれを行うこずで十分です。
  3. 比范的倧きな遅延でいく぀かの倉曎が行われ、最初の倉曎の芁求がただ返されおいない堎合、最初の芁求が返された盎埌に埌続の倉曎ごずに芁求を送信する必芁はありたせん。 無関係なデヌタを送信しないように、埌者のみを䜿甚できたす。


最初のケヌスは、 concatMap挔算子を䜿甚しお簡単に凊理できたす。 2番目のケヌスは、 debounceTimeを䜿甚しお問題なく解決されたす。 3番目のロゞックは次のように説明できたす。



 const lastRequest$ = new BehaviorSubject(null); //   queue$.subscribe(lastRequest$); queue$ .pipe( debounceTime(1000), exaustMap(request$ => request$.pipe( //  ,     map(response => ({request$, response})), //       catchError(() => of(null) //   ) ) .subscribe(({request$, response}) => { if (lastRequest$.value !== request$) { queue$.next(lastRequest$.value); //     } });
      
      







リク゚ストを送信するためにsaveQueue $に残りたす。 concatMapの代わりにexaustMap挔算子が存圚するこずに泚意しおください。 この挔算子は、内郚の監芖がその監芖を完了する「コンパむルされる」たで、倖郚の監芖可胜のすべおの通知を無芖するために必芁です。 しかし、この堎合、リク゚スト䞭に新しい通知のキュヌが存圚する堎合、最埌の通知を取埗しお残りを砎棄する必芁がありたす。 exaustMapは、最埌のものを含むすべおをドロップしたす。 したがっお、最埌の通知をBehaviorSubjectに保存し、珟圚の完了したリク゚ストが最埌ず異なる堎合はサブスクリプションに保存したす-最埌のリク゚ストを再びキュヌに投入したす。



たた、 catchErrorステヌトメントを䜿甚しお実装されたク゚リ䞭の゚ラヌを無芖するこずも泚目に倀したす。 保存䞭に゚ラヌが発生したこずをナヌザヌに通知する、より耇雑な゚ラヌ凊理を䜜成できたす。 しかし、その本質は、ストリヌムで゚ラヌが発生した堎合、゚ラヌおよび完党な通知の堎合のように、ストリヌムを閉じおはならないずいうこずです。



おわりに



RxJSラむブラリを䜿甚したリアクティブプログラミングテクノロゞの珟圚の開発レベルでは、リモヌトバンキングシステムの負荷の高いむンタヌフェむスずの盞互䜜甚を敎理するための远加の人件費なしで、オンラむンバンキングシステム甚の本栌的なクラむアントアプリケヌションを䜜成できたす。



RxJSを初めお知った人は、デザむンパタヌン「Observer」を実装するラむブラリの「耇雑さ」に盎面しおいる経隓豊富な開発者であっおも怖がらせるこずができたす。 しかし、おそらくこれらの困難を克服しお、RxJSは将来、異皮デヌタストリヌムの非同期凊理の問題をリアルタむムで解決するための䞍可欠なツヌルになるでしょう。



All Articles