Tìm kiếm trang web

javascript - Lỗi từ chối không được xử lý Bluebird


Tôi có đoạn mã sau. Và nó hoạt động như mong đợi mà không gây ra lỗi từ chối không xử lý.

p = new Promise (fulfill, reject) ->
  reject new Error 'some error'

p.catch (error) ->
  console.log error

Bây giờ, ví dụ mã thứ hai thực sự ném ra lỗi từ chối không được xử lý. Ai đó có thể giải thích cho tôi tại sao điều này xảy ra khi tôi rõ ràng đang xử lý lỗi không.

p = new Promise (fulfill, reject) ->
  reject new Error 'some error'

p.then ->
  console.log 'ok'

p.catch (error) ->
  console.log error

Nhân tiện, tôi đang thử nghiệm trong Chrome và Bluebird v3.4.7

Câu trả lời #1

Theo cấu hình quản lý lỗi, Bluebird sẽ ném ra lỗi nếu không có trình xử lý catch được đăng ký khi một promise bị từ chối, mà không chờ xem có ai đó thêm vào sau này hay không. Lưu ý rằng việc kiểm tra trình xử lý từ chối nên được thực hiện bất đồng bộ với luồng đã thiết lập chuỗi promise. Như người ta nói, "một số mẫu lập trình sẽ dẫn đến kết quả dương tính giả". Thật vậy sao?

Mặt khác, lỗi ngoại lệ không bắt được không phải là một phần của tiêu chuẩn ES6 và các triển khai xử lý chúng theo những cách khác nhau: Firefox chờ, hoặc đã từng chờ, cho đến thời gian GC trong khi Chrome hết giờ (hoặc đã từng hết giờ) với lỗi "có thể từ chối Promise không bắt được".

Tham khảo tài liệu của Bluebird để tìm các giải pháp có thể cho các lời hứa Bluebird gặp lỗi trước khi gắn trình xử lý.

Nhưng vì cả hai ví dụ đều đồng thời gắn một bộ xử lý từ chối cho promise p, lý do gây ra ngoại lệ dường như nằm ở chỗ khác.

Cảm ơn câu trả lời của @DJ nhưng với một cách giải thích khác. Trong ví dụ thứ hai, then trả về một promise sẽ bị từ chối nếu p bị từ chối, và không có trình xử lý từ chối. Promise được trả về bởi .then có khả năng là cái đang ném ra lỗi.

Câu trả lời #2

Khi bạn xâu chuỗi Promises, mỗi chuỗi được coi như một thể hiện mới của Promise.

catch() giống với then() ngoại trừ bạn chỉ cung cấp bộ xử lý trong trường hợp bị từ chối.

Vì vậy, trong ví dụ 1 của bạn: catch() của bạn dùng để xử lý việc từ chối các promise gốc, nơi lỗi đã được tạo ra.

Trong ví dụ 2: Nó đang nói, khi lời hứa đầu tiên được giải quyết, vui lòng chuyển sang lời hứa thứ 2 nơi bạn cung cấp trình xử lý then cho thành công và thất bại. catch() mà bạn có ở đó là để xử lý lỗi trong hàm bên trong then(), không phải lỗi được tạo ra bởi lời hứa thứ nhất

Xem https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch để biết thêm thông tin về cách catch hoạt động