Bây giờ, rõ ràng, Angular sẽ không "biết", rằng ngOnInit đã trở thành không đồng bộ. Tôi cảm thấy rằng đây không phải là vấn đề: Ứng dụng của tôi vẫn hoạt động như trước đây.
Về mặt ngữ nghĩa, nó sẽ biên dịch tốt và chạy như mong đợi, nhưng sự thuận tiện của việc viết async / wait
đi kèm với chi phí xử lý lỗi, và tôi nghĩ nên tránh.
Hãy xem điều gì sẽ xảy ra.
Điều gì xảy ra khi một lời hứa bị từ chối:
public ngOnInit() {
const p = new Promise((resolver, reject) => reject(-1));
}
Ở trên tạo ra dấu vết ngăn xếp sau:
core.js:6014 ERROR Error: Uncaught (in promise): -1
at resolvePromise (zone-evergreen.js:797) [angular]
at :4200/polyfills.js:3942:17 [angular]
at new ZoneAwarePromise (zone-evergreen.js:876) [angular]
at ExampleComponent.ngOnInit (example.component.ts:44) [angular]
.....
Chúng ta có thể thấy rõ rằng lỗi không được xử lý đã được kích hoạt bởi một ngOnInit
và cũng có thể xem tệp mã nguồn nào để tìm dòng mã vi phạm.
Điều gì xảy ra khi chúng ta sử dụng async/wait
từ chối:
public async ngOnInit() {
const p = await new Promise((resolver, reject) => reject());
}
Ở trên tạo ra dấu vết ngăn xếp sau:
core.js:6014 ERROR Error: Uncaught (in promise):
at resolvePromise (zone-evergreen.js:797) [angular]
at :4200/polyfills.js:3942:17 [angular]
at rejected (tslib.es6.js:71) [angular]
at Object.onInvoke (core.js:39699) [angular]
at :4200/polyfills.js:4090:36 [angular]
at Object.onInvokeTask (core.js:39680) [angular]
at drainMicroTaskQueue (zone-evergreen.js:559) [<root>]
Chuyện gì đã xảy ra? Chúng tôi không có manh mối, vì dấu vết ngăn xếp nằm ngoài thành phần.
Tuy nhiên, bạn có thể bị cám dỗ để sử dụng những lời hứa và tránh sử dụng async / wait
. Vì vậy, hãy xem điều gì sẽ xảy ra nếu một lời hứa bị từ chối sau a setTimeout()
.
public ngOnInit() {
const p = new Promise((resolver, reject) => {
setTimeout(() => reject(), 1000);
});
}
Chúng tôi sẽ nhận được dấu vết ngăn xếp sau:
core.js:6014 ERROR Error: Uncaught (in promise): [object Undefined]
at resolvePromise (zone-evergreen.js:797) [angular]
at :4200/polyfills.js:3942:17 [angular]
at :4200/app-module.js:21450:30 [angular]
at Object.onInvokeTask (core.js:39680) [angular]
at timer (zone-evergreen.js:2650) [<root>]
Một lần nữa, chúng tôi đã mất ngữ cảnh ở đây và không biết phải đi đâu để sửa lỗi.
Các thiết bị quan sát phải chịu các tác dụng phụ tương tự của việc xử lý lỗi, nhưng nhìn chung các thông báo lỗi có chất lượng tốt hơn . Nếu ai đó sử dụng throwError(new Error())
các Lỗi đối tượng sẽ chứa một chồng dấu vết, và nếu bạn đang sử dụng HttpModule
các Lỗi đối tượng thường là một phản ứng Http đối tượng đó nói với bạn về các yêu cầu.
Vì vậy, đạo lý của câu chuyện ở đây: Bắt lỗi của bạn, sử dụng những thứ có thể quan sát được khi bạn có thể và không sử dụng async ngOnInit()
, bởi vì nó sẽ quay trở lại ám ảnh bạn như một lỗi khó tìm và sửa.