Tìm kiếm trang web

javascript - Rxjs toPromise() đã bị lỗi thời


Tôi đã đọc rằng toPromise() đang bị loại bỏ trong RxJS 7 và sẽ bị gỡ bỏ trong RxJS 8. Tôi thường sử dụng nó với cú pháp async await trong Angular để xử lý các cuộc gọi http. Liệu điều này có được coi là một mô hình phản đối (anti pattern) không? Tôi hiểu khái niệm về luồng (streams) nhưng một cuộc gọi http chỉ phát ra một giá trị duy nhất. Tôi không hiểu lý do sử dụng observable cho một cuộc gọi http đơn giản. Tôi nên sử dụng gì tiếp theo? Liệu tôi có nên hoàn toàn áp dụng lập trình phản ứng (reactive programming) không?

Câu trả lời #1

Tại sao điều này lại xảy ra? :

Như đã đề cập ở đây, đây là những lý do chính tại sao toPromise đang bị loại bỏ:

  1. Một mục tiêu là loại bỏ nó khỏi prototype Observable và biến nó thành một hàm tiện ích độc lập.

  2. Tên gọi của toPromise không phải là tốt nhất. Đặc biệt khi sử dụng kết hợp với await, nó không đọc được một cách rõ ràng: await categories$.toPromise() so với await lastValueFrom(categories$)

  3. Thông tin kiểu của toPromise là sai. Khi nguồn Observable hoàn tất mà chưa bao giờ phát ra một giá trị nào - nó sẽ được giải quyết với undefined. Trong trường hợp đó nên từ chối. Một Promise là một “lời hứa” rằng khi nó được giải quyết sẽ có một giá trị - và một giá trị có thể là undefined. Nhưng khi luồng hoàn tất mà chưa từng phát ra giá trị nào, bạn không thể phân biệt được giữa một luồng đã phát undefined một cách cố ý và một luồng đã hoàn tất mà không bao giờ phát thêm gì nữa.

Bạn nên sử dụng gì tiếp theo? :

Nếu bạn thực sự cố chấp làm theo cách hứa hẹn, lastValueFrom/firstValueFrom. Nếu không, chuyển sang lập trình phản ứng sẽ là cách nên làm.

Sử dụng toPromise (đã bị ngừng sử dụng) -

public async loadCategories() {
    this.categories = await this.inventoryService
      .getCategories()
      .toPromise()
}

Sử dụng lastValueFrom (mới) -

import { lastValueFrom } from 'rxjs';

public async loadCategories() {
    const categories$ = this.inventoryService.getCategories();
    this.categories = await lastValueFrom(categories$);
} 

Liên kết này nên giúp được -

https://indepth.dev/posts/1287/rxjs-heads-up-topromise-is-being-deprecated

Câu trả lời #2

firstValueFrom và lastValueFrom chắc chắn là một lựa chọn tốt hơn vì nhiều lý do:

  1. Tên gọi dễ đọc hơn và tự giải thích.
  2. Khả năng bổ sung để chọn giá trị đầu tiên hoặc cuối cùng.
  3. Khả năng bổ sung để khai báo một giá trị mặc định trong trường hợp observable không phát ra bất kỳ giá trị nào cả như sau await lastValueFrom(data$, {defaultValue: 'Some default value'})

Để biết thêm về điều này, hãy xem video bên dưới:
https://www.youtube.com/watch?v=3aeK5SfWBSU

Câu trả lời #3

Ví dụ mã:

Sử dụng không được khuyến nghị:

await this.http.post<boolean>(`/someApi`).toPromise()
  .then((value) => {
    console.log(`Result: ` + value);
  })

Mã mới:

import { firstValueFrom } from 'rxjs';

await firstValueFrom(this.http.post<boolean>(`/someApi`))
  .then((value) => {
    console.log(`Result: ` + value);
  })

Bài viết liên quan