Please enable JavaScript.
Coggle requires JavaScript to display documents.
Angular - Coggle Diagram
Angular
RxJs
- Khái Niệm: RxJS là một thư viện để biên soạn các chương trình bất đồng bộ và dựa trên sự kiện bằng cách sử dụng các chuỗi có thể quan sát được. nó cung cấp một core type, Observable, các loại satellite types (Observer, Schedulers, Subjects) và các toán tự dựa trên Array (map,filter, reduce, every, etc) để xử lý sự kiện bất đồng bộ dưới dạng các bộ sưu tập.
- Khái niệm trọng tâm: Observable, Observer, Subcription, Operators, Subject, Scheduler
- Khái niệm: là một đại diện cho một dòng dữ liệu hoặc sự kiện có thể xảy ra trong tương lai, và cho phép đăng ký để nhận các giá trị hoặc sự kiện khi chúng xuất hiện.Observable sẽ điều phối nó đến Observe.
- nó chỉ là một function(class) mà nó có một số yêu cầu đặc biệt. nhận vào một function, mà function này nhận đầu vào là một Observer và trả về một function để có thể thực hiện cancel quá trình xử lý
- Khái niệm: là một tập hợp các callbacks tương ứng cho việc lắng nghe các giá trị (next, error, hay complete) được gửi đến bởi Observable
- Khái niệm: là kết quả có được sau khi thực hiện một Observable, nó thường dùng cho việc hủy việc tiếp tục xử lý
- Khái niệm: là các pure function cho phép lập trình functional với Observable
- Khái niệm: để thực hiện việc gửi dữ liệu đến nhiều Observers
- Khái niệm: nó điều khiển khi nào một subcription bắt đầu thực thi, và khi nào sẽ gửi tín hiệu đi
- Khởi tạo: gọi constructor và truyền vào 1 function (gọi là subcribe), trong đó cái function này nhận đầu vào là một Observer
- Invoking: nếu bạn có một Observable, thí nó chỉ khai báo như một function, do đó những gì có trong một function sẽ không được được chạy cho đến khi bạn invoke function đó. để invoke, chỉ cần subcribe vào nó, rồi nó sẽ trả về một subcription
- Thực thi: khi chúng ta khởi tạo Observable và invoke một Observable thì nó bắt đầu chạy, và khi có một signal nào (next, error, complete) gửi đi thì những gì chúng ta cung cấp cho Observer phía trên sẽ được gọi để tương tác lại tín hiệu đó.
- “Next” notification: gửi đi một giá trị, có thể là bất kỳ kiểu dữ liệu nào như Number, a String, an Object, etc.
- “Error” notification: gửi đi một JavaScript Error hoặc exception
- “Complete” notification: không gửi đi một giá trị nào, nhưng nó gửi đi một tín hiệu để báo rằng stream này đã completed, mục đích để Observer có thể thực hiện một hành động nào đó khi stream completed.
- Observers: là một object chứa một tập 3 callbacks tương ứng cho mỗi loại notification được gửi từ Observable: next, error, complete
- nó được cung cấp là tham số đầu vào của subscribe để kích hoạt Observable execution
- Subcription: là một object đại diện cho một nguồn tài nguyên có khả năng hủy được, thông thường trong Rxjs là hủy Observable execution,Subscription có chứa một method quan trọng unsubscribe
- Một Subscription có thể chứa trong nó nhiều Subscriptions con, khi Subscription unsubscribe, các Subscriptions con cũng sẽ unsubscribe.
-Ở Subscription cha, chúng ta có thể gọi method add để thêm các Subscriptions con mà phụ thuộc Subscription cha này.
- From: giống of chỉ khác là nhận vào giá trị là một Iterable(các loại giá trị có thể duyệt qua(iterate)) hoặc là một Promise. rồi tạo observerble.
- FromEvent: chuyển đổi một sự kiện(event) thành observerble. observerble này không tự complete(hiển nhiên thôi, phải đợi event mà) vậy nên phải tự unsubcribe khi cần thiết để tránh tràn memory
- fromEventPattern: là bản nâng cao của fromEvent, cung cấp 1 API để có thể chuyển đổi các sự kiện từ API gốc của sự kiện
- Interval: là hàm để tạo Observable mà sẽ emit giá trị số nguyên từ số 0 theo 1 chu kỳ nhất định. Hàm này giống với setInterval
- timer: Tạo Observable mà sẽ emit giá trị sau khi delay 1 khoảng thời gian nhất định. Cách dùng này sẽ tự complete nhé.
- throwError: sẽ dùng để tạo Observable mà thay vì emit giá trị, Observable này sẽ throw 1 error ngay lập tức sau khi subscribe
- defer: nhận vào 1 ObservableFactory và sẽ trả về Observable này. Điểm đặc biệt của defer() là ở việc defer() sẽ dùng ObservableFactory này để tạo 1 Observable mới cho mỗi Subscriber
- Of: tạo một Observble từ bất cứ giá trị gì, complete ngay sau khi các giá trị được emit.
- Khái niệm Pipeable Operators:Một Pipeable Operator là một function nó nhận đầu vào là một Observable và returns một Observable khác
- Map: lặp qua observable và trả về observable mới. có thể thực hiện logic hay transform trong map
- Pluck: dùng như map, nhưng có thể truyền vào property để hiển thị ra ở next
- Mapto:bất cứ khi nào stream emit một giá trị thì luôn trả về một giá trị fixed
- scan: giống reduce, apply một function lên value emit ra có kèm theo kết quả lưu trữ trước đó
- reduce: sẽ reduce value overtime, nhưng nó sẽ đợi đến khi source complete rồi thì nó mới emit một giá trị cuối cùng và gửi đi complete
- ToArray: ollect toàn bộ các value emit bởi stream rồi lưu trữ thành một array
- Buffer: Lưu trữ giá trị được emit ra và đợi đến khi closingNotifier emit thì emit những giá trị đó thành 1 array.
- bufferTime: Tương tự như buffer, nhưng emit values mỗi khoảng thời gian bufferTimeSpan ms.
- mục đích: lọc/lược các giá trị emit từ Observable gốc
- filter(): nhận vào một predecate là 1 function (function này return ra truthy, hoặc falsy) nếu function trả về truthy thì emit giá trị của Observable ngược lại không in
- first(): emit ra giá trị đầu tiên của 1 Observable rồi complete. nó có thể nhận vào 2 tham số là predecate, defaultValue khi đó nó hoạt động như firstOrDefault().
- last(): ngược lại với first
- find(): emit ra giá trị đầu tiên mà thỏa mãn được điều kiện từ predicate rồi complete. (khác với first ở chỗ là find phải có predicte và không emit error nếu không có giá trị nào thỏa mãn điều kiện)
- single(): hoạt động như first nhưng chặt chẽ hơn vì sẽ error nếu như có nhiều hơn 1 giá trị thỏa mãn điều kiện
- take(): nhận vào 1 tham số count để dùng cho số lần lấy giá trị được emit từ Observable sau đó sẽ complete
- takeLast(): giống take() nhưng sẽ lấy n giá trị cuỗi cùng được emit từ Observable (chỉ emit khi nào Observable gốc complete)
- takeUntil(): nhận vào 1 tham số là Observable như 1 notifier và sẽ emit giá trịn của Observable gốc cho tới khi notifier emit.
nó được dùng để unsubcribe Observable trong ngOnDestroy()
- takeWhile(): giống takeUntil() nhưng nhận vào predecate,
- skip(): giống take() nhưng ngược lại với take() bỏ qua n giá trị đầu
- skhipUntil và SkipWhile: giống với takeUntil và takeWhle
- distinct(): distinct() sẽ so sánh các giá trị được emit từ Observable và chỉ emit các giá trị chưa được emit quacó thể nhận vào 1 tham số là hàm keySelector để có thể chọn được property nào cần được so sánh nếu như Observable emit giá trị là 1 complex Object
- distinctUntilChanged(): so sánh giá trị sắp được emit với giá trị vừa được emit (giá trị cuối) chứ không so sánh với tất cả giá trị đã được emit.
- throttle()/throttleTime(): throttleTime() nhận vào 1 tham số là duration có đơn vị là millisecond. Khi Observable gốc emit giá trị đầu tiên, throttleTime() sẽ emit giá trị này rồi sẽ chạy timer với duration được truyền vào. Khi timer đang chạy thì mọi giá trị của Observable gốc emit đều được bỏ qua. Khi timer chạy xong, throttleTime() quay lại trạng thái ban đầu và chờ giá trị kế tiếp của Observable gốc.
- debounce()/debounceTime(): debounceTime() nhận vào 1 tham số là dueTime có đơn vị là millisecond. Khi Observable gốc emit giá trị, debounceTime() sẽ bỏ qua giá trị này và sẽ chạy timer với khoảng thời gian dueTime. debounceTime() sẽ bỏ qua tất cả giá trị mà Observable gốc emit trong khi timer vẫn đang chạy và sau đó debounceTime() sẽ chạy lại timer. Khi và chỉ khi timer được chạy hoàn chỉnh khoảng thời gian dueTime, debounceTime() sẽ emit giá trị cuối cùng mà Observable gốc đã emit
- audit()/auditTime(): auditTime() nhận vào 1 tham số duration có đơn vị là milliseconds. auditTime() hoạt động tương tự throttleTime() với {trailing: true}. Nghĩa là sau khi timer chạy và chạy xong duration, auditTime() sẽ emit giá trị gần nhất mà Observable gốc emit.
- sample()/sampleTime(): sampleTime() nhận vào 1 tham số là period có đơn vị là millisecond. Khi Observable gốc được subscribe, timer của sampleTime() sẽ chạy ngay lập tức và cứ sau mỗi period, sampleTime() sẽ emit giá trị gần nhất của Observable gốc.
- khái niệm: là những toán tử giúp kết hợp nhiều observable lại với nhau theo những cách khác nhau
- forkjoin(): nhận vào tham số là 1 list các Observables theo dạng Array hoặc Dictionary (Object) (children). Khi các children Observables complete hết thì forkJoin() sẽ emit giá trị của các children Observables theo dạng Array hoặc Dictionary (tuỳ vào tham số truyền vào) rồi sau đó sẽ complete.
- combineLatest(): không nhận vào Dictionary (Object) và combineLatest() sẽ emit khi TẤT CẢ các children Observables emit ít nhất một lần, nghĩa là các children Observables không cần phải complete mà chỉ cần emit ít nhất 1 giá trị thì combineLatest() sẽ emit giá trị là Array gồm tất cả các giá trị được children Observables emit, theo thứ tự
- Zip: nhận vào tham số là ...(Observables | Function) để tượng trưng cho các child Observable được truyền vào lần lượt. zip() là 1 operator khá hay ho vì zip() sẽ gom tất cả các giá trị được emit bởi children Observable theo cặp (hiểu nôm na là nó emit theo cặp)
- Concat(): concat() sẽ subscribe vào các children Observables theo thứ tự được truyền vào và sẽ emit khi Observable đang được subscribe complete
- Meger(): sẽ subscribe vào tất cả (phụ thuộc vào tham số concurrent nếu được truyền vào) các children Observables, complete khi và chỉ khi tất cả children Observables complete.
- Race(): sẽ emit giá trị của Observable nào emit đầu tiên (nhanh nhất) sau đó lặp lại cho đến khi 1 trong các children Observables complete.
- withLatestFrom(): nhận vào tham số là 1 Observable. withLatestFrom() sẽ gộp giá trị emit của Outer Observable với giá trị gần nhất của tham số Observable thành 1 Array rồi emit Array này
- startWith(): nhận vào 1 list các tham số. startWith() sẽ làm cho cả Observable emit giá trị của startWith() trước rồi mới emit đến giá trị của Outer Observable. startWith() sẽ emit giá trị ngay lặp tức mà không phụ thuộc vào việc Outer Observable có emit hay là chưa.
- endWith(): cũng nhận vào 1 list các tham số như startWith() nhưng cách hoạt động thì ngược lại với startWith(). Một điểm khác biệt lớn là endWith() chỉ emit giá trị của endWith() khi Outer Observable complete mà thôi.
- pairwise(): sẽ gộp giá trị emit gần nhất và giá trị đang được emit của Outer Observable thành 1 Array (1 cặp giá trị) và emit Array này
- Error Handling and Conditional Operators
- catchError(): bắt được lỗi và muốn xử lý lỗi đó, ví dụ: biến đổi Error thành một value thông thường, tránh bị terminate stream.
- retry(): resubscribe vào source Observable khi có error emit từ source. Nếu chúng ta không truyền gì vào cho param count, lúc này nó có thể retry không giới hạn số lần. Ngược lại, nó sẽ retry max số lần được truyền vào.
- defaultIfEmpty/throwIfEmpty(): Hai operators này cho phép chúng ta trả về các giá trị tương ứng (default value hoặc Error) nếu source stream là empty (không emit value nào mà chỉ có complete).
- every(): Opeator này sẽ trả về true nếu tất cả các value emit của source thỏa mãn hàm predicate
- iif(): Opeartor này cho phép chúng ta lựa chọn Observable tương ứng với hàm điều kiện khi thực hiện subscribe, nhận vào 1 predecate(làm điều kiện) và 2 observable sau đó, tùy theo điều kiện mà subcriber vào observable thích hợp. (condition: () => boolean, trueResult: SubscribableOrPromise<T> = EMPTY, falseResult: SubscribableOrPromise<F> = EMPTY)
- HOOS and untility Operator
- MergeMap(): mergeMap() sẽ không unsubscribe Inner Observable cũ nếu như có Inner Observable mới. Nói đúng hơn, mergeMap() sẽ giữ nhiều Subscription. Vì tính chất này, mergeMap() thích hợp khi bạn có nghiệp vụ mà không cần/được dừng Inner Observable nếu như Outer Observable có emit giá trị mới.... Operator này còn nhận vào một tham số là concurrent giống như merge operator để control có bao nhiêu Inner Observable có thể chạy đồng thời.
- concatMap(): concatMap() sẽ subscribe vào Inner Observable và sẽ CHỜ cho đến khi Inner Observable này complete thì mới subscribe vào Inner Observable tiếp theo (nếu như có Inner Observable tiếp theo)
- exhaustMap(): exhaustMap() sẽ subscribe vào Inner Observable này và trong khi Inner Observable đang emit (chưa complete) giá trị của nó mà có 1 Inner Observable mới (do Outer Observable emit giá trị mới, nhớ nha các bạn 👌) thì Inner Observable mới này sẽ bị BỎ QUA hoàn toàn khi Inner Observable cũ chưa complete.
- switch/concat/mergeMapTo(): Cách thức hoạt động giống với HOO nguyên bản. Tuy nhiên, thay vì nhận vào projectFunction thì các bạn truyền hẳn vào Inner Observable luôn
- partition(): nhận vào 2 param : 1 là source observable, 1 là predecatefunction => function này là 1 điều kiện. partition sẽ emit ra 2 distination observable là 1 ob thỏa mãn điều kiện predicate, còn 1 ob là không thỏa mãn điều kiện predicate
- switchMap(): sẽ nhận vào một projectFunction mà sẽ nhận vào giá trị được emit từ Outer Observable và sẽ phải trả về 1 Observable (Inner Observable) mới. Giá trị cuối cùng của Outer Observable khi dùng với switchMap() sẽ là giá trị mà Inner Observable subcribe. switchMap() sẽ unsubscribe Inner Observable(là giá trị mà outer observable emit ra) nếu như Inner Observable đang được subscribe chưa complete MÀ Outer Observable lại emit tiếp.
- Khái niệm: là những operators mà sẽ nhận vào giá trị của Outer Observable (hay còn gọi là Source) và sẽ trả về một Inner Observable (hay còn gọi là Destination) khác
- Tap(): là 1 operator mà các bạn có thể pipe vào bất cứ Observable nào và tại bất cứ vị trí nào. tap() nhận vào tham số giống như subscribe đó là Observer hoặc là 3 functions nextFunction, errorFunction, và completeFunction. Vì nhận vào tham số giống subscribe, nên bản chất tap() không trả về giá trị gì. Điều này nghĩa là tap() hoàn toàn không làm thay đổi bất cứ gì trên 1 Observable
- cách dùng: đây là các operator cung cấp tiện ích cho observable
- delay()/delayWhen(): chỉ là delay giá trị emit của 1 Observable nào đó dựa vào tham số truyền vào. Nếu như tham số truyền vào là Number, thì delay() sẽ chạy 1 timer với khoảng thời gian là tham số, sau đó sẽ emit giá trị của Observable. Nếu như tham số truyền vào là Date, thì delay() sẽ hoãn giá trị emit tới khi thời gian hiện tại bằng với Date được truyền vào. delayWhen() tính chất hoạt động giống như delay() truyền vào 1 function mà trả về 1 Observable. delayWhen() sẽ hoãn emit giá trị của Source Observable cho đến khi Observable truyền vào emit.
- finalize(): nhận vào 1 callback. callback này sẽ được thực thi khi Observable complete hoặc error. Use-case thường gặp nhất của finalize() chính là stop loader/spinner
- repeat(): đúng như tên gọi, sẽ nhận vào tham số count và sẽ lặp lại Source Observable đúng với số count mà được truyền vào.
- timeInterval(): dùng để đo khoảng thời gian giữa 2 lần emit của Source Observable.
- timeout(): nhận vào tham số giống như delay(), là 1 khoảng thời gian Number hoặc 1 ngày nào đó Date. timeout() sẽ throw error nếu như Source Observable không emit giá trị trong khoảng thời gian (nếu như tham số là Number) hoặc cho tới khi thời gian hiện tại bằng với ngày được truyền vào (nếu như tham số là Date).
- timeoutWith(): hoạt đột tương tự timeout() nhưng nhận thêm tham số thứ 2 là 1 Observable. Nếu như trường hợp Source Observable emit giá trị quá chậm so với due thì timeoutWith() thay vì throw error, timeoutWith() sẽ subscribe vào tham số Observable kia
- toPromise(): toPromise() là 1 instance method trên class Observable dùng để chuyển đổi 1 Observable thành Promise🤦. Tuy nhiên, toPromise() sẽ bị deprecated vào RxJS v7 sắp tới, các bạn nào dùng thì cẩn thận nhé
- Observable Execution: mỗi lần subcribe vào observable nó sẽ sinh ra một execution
- Subject: Do Subject vừa là một Observable (chúng ta có thể subscribe vào nó), vừa là một Observer (có các method để chúng ta tự control khi nào gửi notification). nên dùng khá nhiều
- BehaviorSubject: lưu trữ lại giá trị mới emit gần nhất để khi một Observer mới subscribe vào, nó sẽ emit giá trị đó ngay lập tức cho Observer vừa rồi.Lưu ý: BehaviorSubject yêu cầu phải có giá trị khởi tạo khi tạo ra subject.
- ReplaySubject: Một ReplaySubject tương tự như một BehaviorSubject khi nó có thể gửi những dữ liệu trước đó cho Observer mới subscribe, nhưng nó có thể lưu giữ nhiều giá trị (có thể là toàn bộ giá trị của stream từ thời điểm ban đầu). Tham số đầu vào của ReplaySubject có thể là:buffer: là số lượng phần tử tối đa có thể lưu trữ. windowTime: (ms) thời gian tối đa tính đến thời điểm gần nhất emit value.
- AsyncSubject: Đây là biến thể mà chỉ emit giá trị cuối cùng của Observable execution cho các observers, và chỉ khi execution complete.
- Subject Completion: Khi BehaviorSubject complete, thì các Observers subscribe vào sau đó sẽ chỉ nhận được complete signal.Khi ReplaySubject complete, thì các Observers subscribe vào sau đó sẽ được emit tất cả các giá trị lưu trữ trong buffer, sau đó mới thực thi complete của Observer.Kể cả khi AsyncSubject complete rồi, Observer vẫn có thể subscribe vào được và vẫn nhận giá trị cuối cùng.
- Quay trở lại vấn đề ban đầu khi chúng ta mong muốn multicast. Chúng ta mong muốn cả hai observer đều chạy cùng một execution.Chúng ta sẽ có thể thay thế bằng cách dùng multicast operator.
- multicast(subject): Operator này sẽ trả về một Observable đặc biệt là ConnectableObservable, mà nó có thể share cùng một execution.
- refCount: Việc phải connect và disconnect manually khá là low level. Do đó ConnectableObservable có một protocol khá thuận tiện đó là: Khi có sự biến đổi về số lượng Observer từ 0 lên 1 thì sẽ tự gọi connect, và khi có sự biến đổi từ 1 về 0 thì sẽ tự động unsubscribe. Đây chính là lúc bạn có thể sử dụng đến refCount
- SubjectFactory: SubjectFactory là một function, nó sẽ trả về một Subject mới khi được gọi. Và khi có sự thay đổi refCount từ 0 => 1, nó sẽ được gọi và bắt đầu được chạy.
- publish(): Việc sử dụng multicast(new Subject()) có thể được viết gọn lại bằng cách sử dụng publish.Ngoài ra, giống như Subject có các biến thể thì publish cũng có các biến thể tương ứng với một số loại Subject.
- share(): = multicast(() => new Subject()) + refCount ;)) tôi cũng không biết sinh ra nhiều như khái niệm như thế làm gì
- shareReplay: shareReplay cho phép các Observer mới nhận lại một số lượng giá trị đã được phát trước đó (replay), giúp tránh việc phải khởi động lại luồng dữ liệu hoặc thực hiện lại các tác vụ tốn tài nguyên như gọi API, kết nối với server, hay xử lý tính toán phức tạp.Observable sau khi áp dụng shareReplay sẽ hoạt động như một luồng chia sẻ (shared stream), nghĩa là các Observer đăng ký sau sẽ nhận lại giá trị đã được phát ra mà không làm gián đoạn hoặc tái khởi động luồng gốc.
Route
- Khái niệm: Route (tuyến đường) là một thành phần quan trọng của hệ thống định tuyến (routing), giúp quản lý điều hướng trong ứng dụng web. Route định nghĩa các đường dẫn URL mà ứng dụng sẽ phản hồi, từ đó kết hợp các URL với các thành phần tương ứng hiển thị giao diện người dùng.
- Route là một đối tượng JavaScript, trong đó bạn định nghĩa các cặp đường dẫn URL và các thành phần (components) sẽ được tải khi người dùng truy cập vào URL đó. Mỗi Route bao gồm các thuộc tính cơ bản như path (đường dẫn) và component (thành phần hiển thị)