hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Cấu trúc dữ liệu và giải thuật
    • Lập Trình C# Cơ Bản
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Angular
  • Học lập trình
  • Lập trình Javascript
RxJS Creation Operators trong RxJS

RxJS Creation Operators trong RxJS

  • 26-12-2023
  • Toanngo92
  • 0 Comments

RxJS Creation Operators là các công cụ mạnh mẽ trong RxJS giúp tạo Observable một cách dễ dàng và linh hoạt hơn so với việc tạo bằng tay. Trong bài trước, chúng ta đã thấy cách tạo một Observable thủ công bằng cách sử dụng constructor. Nhưng liệu có cách nào khác không? Đây chính là nơi mà các Operators trong RxJS sẽ giúp ích cho chúng ta.

Các Operators là những hàm pure cho phép chúng ta thực hiện các thao tác functional trên Observable một cách dễ dàng và linh hoạt.

Để bắt đầu, dưới đây là đoạn mã cho observer mà chúng ta sẽ sử dụng trong các ví dụ tiếp theo:

const observer = {
  next: (val) => console.log(val),
  error: (err) => console.log(err),
  complete: () => console.log("complete"),
};

Mục lục

  • Common Creation Operators
    • Hàm of()
    • Hàm from()
    • Hàm fromEvent()
    • Hàm fromEventPattern()
    • Hàm interval()
    • Hàm timer()
    • Hàm throwError()
    • Hàm defer()

Common Creation Operators

Hàm of()

Hàm of() trong RxJS giúp tạo Observable từ hầu hết mọi giá trị: từ các kiểu dữ liệu cơ bản như số, chuỗi, tới các cấu trúc phức tạp như mảng, đối tượng, hoặc cả hàm. Khi sử dụng of(), Observable sẽ emit các giá trị được truyền vào và sau đó hoàn thành ngay sau khi tất cả các giá trị đó đã được phát đi.

Ví dụ với giá trị cơ bản:

// output: 'hello'
// complete: 'complete'
of("hello").subscribe(observer);

Hoặc với mảng hoặc đối tượng:

// output: [1, 2, 3]
// complete: 'complete'
of([1, 2, 3]).subscribe(observer);

Bạn cũng có thể truyền nhiều giá trị vào of() để tạo một chuỗi giá trị sẽ được emit:

// output: 1, 2, 3, 'hello', 'world', {foo: 'bar'}, [4, 5, 6]
// complete: 'complete'
of(1, 2, 3, "hello", "world", { foo: "bar" }, [4, 5, 6]).subscribe(observer);

Khi bạn sử dụng of(), Observable sẽ phát đi các giá trị này tuần tự và hoàn thành sau khi phát hết tất cả các giá trị đã được truyền vào.

Hàm from()

Hàm from() trong RxJS tương tự như of(), nhưng khác biệt ở chỗ from() nhận vào một Iterable hoặc một Promise để tạo Observable.

Iterable là bất kỳ giá trị nào bạn có thể duyệt qua như mảng (array), map, set hoặc thậm chí là chuỗi (string). Khi duyệt qua chuỗi, bạn sẽ nhận được từng ký tự một.

  • Ví dụ với Array:
// output: 1, 2, 3
// complete: 'complete'
from([1, 2, 3]).subscribe(observer);

Khi nhận vào một mảng, from() sẽ phát đi các giá trị trong mảng theo trình tự. Điều này tương đương với of(1, 2, 3).

  • Hoặc với String:
// output: 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'
// complete: 'complete'
from("hello world").subscribe(observer);
  • from() cũng có thể nhận các cấu trúc dữ liệu như Map hoặc Set:
const map = new Map();
map.set(1, "hello");
map.set(2, "bye");
// output: [1, 'hello'], [2, 'bye']
// complete: 'complete'
from(map).subscribe(observer);

const set = new Set();
set.add(1);
set.add(2);
// output: 1, 2
// complete: 'complete'
from(set).subscribe(observer);

Ngoài ra, from() có khả năng chuyển đổi Promise thành Observable:

// output: 'hello world'
// complete: 'complete'
from(Promise.resolve("hello world")).subscribe(observer);

Với Promise, from() sẽ giải quyết (resolve) Promise và trả về giá trị đã được giải quyết. Điều này cho phép bạn chuyển đổi Promise thành Observable.

Hàm fromEvent()

Hàm fromEvent() trong RxJS cho phép chuyển đổi các sự kiện (Events) như click chuột hoặc nhập input thành Observable.

Ví dụ, khi chúng ta có các sự kiện DOM như click chuột hoặc bàn phím:

const btn = document.querySelector("#btn");
const input = document.querySelector("#input");

// output (ví dụ): MouseEvent {...}
// complete: không có gì log.
fromEvent(btn, "click").subscribe(observer);

// output (ví dụ): KeyboardEvent {...}
// complete: không có gì log.
fromEvent(input, "keydown").subscribe(observer);

Điều quan trọng cần lưu ý là fromEvent() tạo ra một Observable không tự động kết thúc (complete) sau khi các sự kiện xảy ra. Điều này là hoàn toàn hợp lý vì chúng ta thường muốn tiếp tục lắng nghe các sự kiện như click hay keydown cho đến khi chúng ta không cần thiết nữa. fromEvent() không thể tự động nhận biết được khi nào chúng ta không muốn lắng nghe các sự kiện nữa. Điều này cũng đồng nghĩa rằng, nếu không cần thiết nữa, bạn cần chủ động unsubscribe các Observable được tạo từ fromEvent() để tránh tràn bộ nhớ (memory leak).

Hàm fromEventPattern()

Hàm fromEventPattern() trong RxJS là một phiên bản nâng cao của fromEvent(). Dù cả hai đều tạo Observable từ sự kiện, nhưng cách sử dụng và cách xử lý loại sự kiện khác biệt nhau.

Ví dụ với sự kiện click:

// Sử dụng fromEvent() như đã biết
// output: MouseEvent {...}
fromEvent(btn, "click").subscribe(observer);

// Sử dụng fromEventPattern()
// output: MouseEvent {...}
fromEventPattern(
  (handler) => {
    btn.addEventListener("click", handler);
  },
  (handler) => {
    btn.removeEventListener("click", handler);
  }
).subscribe(observer);

Ví dụ khác: Lấy tọa độ của con trỏ khi click vào một phần tử:

// Sử dụng fromEvent() với xử lý map
// output: 10 10
fromEvent(btn, "click")
  .pipe(map((ev: MouseEvent) => ev.offsetX + " " + ev.offsetY))
  .subscribe(observer);

// Sử dụng fromEventPattern() với các hàm riêng
function addHandler(handler) {
  btn.addEventListener("click", handler);
}
function removeHandler(handler) {
  btn.removeEventListener("click", handler);
}
// output: 10 10
fromEventPattern(
  addHandler,
  removeHandler,
  (ev: MouseEvent) => ev.offsetX + " " + ev.offsetY
).subscribe(observer);

fromEventPattern() chấp nhận 3 tham số: addHandler, removeHandler, và projectFunction (optional). Nó cung cấp một cách để chuyển đổi các sự kiện từ API gốc sang Observable. Ví dụ, bạn có thể sử dụng nó để xử lý các sự kiện phức tạp hơn từ SignalR Hub hoặc các API khác. Trong ví dụ cuối cùng, chúng ta thấy cách sử dụng fromEventPattern() để kết nối với SignalR Hub thông qua websocket và chuyển đổi các sự kiện thành Observable.

Hàm interval()

Hàm interval() trong RxJS tạo ra một Observable để phát ra các số nguyên từ 0 theo một chu kỳ cố định, tương tự như setInterval().

// output: 0, 1, 2, 3, 4, ...
interval(1000) // phát ra giá trị mỗi giây
  .subscribe(observer);

Tương tự như fromEvent(), interval() cũng không kết thúc tự động, vì vậy bạn cần phải gọi unsubscribe để dọn dẹp khi không cần thiết nữa.

Hàm timer()

Hàm timer() trong RxJS có hai cách sử dụng:

  1. Tạo một Observable sẽ phát ra giá trị sau một khoảng thời gian chờ xác định. Cách này sẽ kết thúc tự động khi phát ra giá trị.
// output: sau 1 giây -> 0
// complete: 'complete'
timer(1000).subscribe(observer);

2. Tạo một Observable sẽ phát ra giá trị sau một khoảng thời gian chờ xác định và sau đó sẽ phát ra giá trị với một chu kỳ cố định. Tương tự như interval(), nhưng timer() hỗ trợ delay trước khi bắt đầu phát ra giá trị. Cách này cũng không kết thúc tự động.

// output: sau 1 giây -> 0, 1, 2, 3, 4, 5 ...
timer(1000, 1000).subscribe(observer);

Hàm throwError()

Hàm throwError() trong RxJS tạo ra một Observable không phát ra giá trị, thay vào đó, ngay khi được subscribe, nó sẽ gây ra một lỗi ngay lập tức.

// error: 'an error'
throwError("an error").subscribe(observer);

throwError() thường được sử dụng để xử lý lỗi trong các Observable. Sau khi xử lý lỗi, khi chúng ta muốn tiếp tục thông báo lỗi cho một ErrorHandler hoặc một phần xử lý lỗi khác, chúng ta có thể sử dụng throwError. Trong các trường hợp làm việc với Observable và các operators yêu cầu một Observable (như switchMap, catchError), việc throwError trả về một Observable là cực kỳ hữu ích.

Hàm defer()

Hàm defer() trong RxJS có một đặc điểm đặc biệt: nó nhận vào một ObservableFactory và mỗi khi có một Subscriber mới, nó sẽ sử dụng ObservableFactory này để tạo ra một Observable mới. Điều này tạo ra sự khác biệt lớn so với các hàm tạo Observable khác như of().

// Sử dụng of()
const now$ = of(Math.random());
// Kết quả giống nhau cho cả 3 lần subscribe
now$.subscribe(observer);
now$.subscribe(observer);
now$.subscribe(observer);

Nhưng khi sử dụng defer(), mỗi lần subscribe sẽ tạo ra một giá trị mới.

const now$ = defer(() => of(Math.random()));
// Mỗi lần subscribe, giá trị được tạo mới
now$.subscribe(observer);
now$.subscribe(observer);
now$.subscribe(observer);

Việc này có ích như thế nào? Giả sử chúng ta cần thử lại một Observable sau mỗi lần lỗi xảy ra, và cần sử dụng một giá trị ngẫu nhiên để quyết định việc thử lại. Trong trường hợp này, defer() kết hợp với retry() sẽ giúp chúng ta rất hiệu quả.

Bài viết liên quan:

Sắp xếp sủi bọt – Bubble Sort
TypeScript với Kiểu Dữ Liệu Cơ Bản – 3
TypeScript với Kiểu Dữ Liệu Cơ Bản – 2
TypeScript với Kiểu Dữ Liệu Cơ Bản – 1
Typescript cơ bản và cách cài đặt cho người mới
Thực Hành Micro Frontends
Dynamic Component trong Angular
Async Validator trong Angular Form
Reactive Forms Trong Angular (Phần 2)
Reactive Forms Trong Angular (Phần 1)
Template-driven Forms Trong Angular (Phần 2)
Template-driven Forms Trong Angular (Phần 1)

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

2. PHÂN TÍCH VÀ ĐẶC TẢ HỆ THỐNG

1. TỔNG QUAN KIẾN THỨC THỰC HÀNH TRIỂN KHAI DỰ ÁN CÔNG NGHỆ THÔNG TIN

Hướng dẫn tự cài đặt n8n comunity trên CyberPanel, trỏ tên miền

Mẫu prompt tạo mô tả chi tiết bối cảnh

Một số cải tiến trong ASP.NET Core, Razor Page, Model Binding, Gabbage collection

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×