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ỏ:
Một mục tiêu là loại bỏ nó khỏi prototype
Observablevà biến nó thành một hàm tiện ích độc lập.Tên gọi của
toPromisekhông phải là tốt nhất. Đặc biệt khi sử dụng kết hợp vớiawait, nó không đọc được một cách rõ ràng:await categories$.toPromise()so vớiawait lastValueFrom(categories$)Thông tin kiểu của
toPromiselà sai. Khi nguồnObservablehoà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ớiundefined. Trong trường hợp đó nên từ chối. MộtPromiselà 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átundefinedmộ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:
- Tên gọi dễ đọc hơn và tự giải thích.
- Khả năng bổ sung để chọn giá trị đầu tiên hoặc cuối cùng.
- 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);
})
