Jadi, pada dasarnya Anda bertanya apa perbedaan antara keduanya (di mana p
janji dibuat dari beberapa kode sebelumnya):
return p.then(...).catch(...);
dan
return p.catch(...).then(...);
Ada perbedaan baik ketika p menyelesaikan atau menolak, tetapi apakah perbedaan itu penting atau tidak tergantung pada apa yang dilakukan kode di dalam .then()
atau .catch()
penangan.
Apa yang terjadi jika p
teratasi:
Dalam skema pertama, saat p
diselesaikan, .then()
penangan dipanggil. Jika .then()
penangan tersebut mengembalikan nilai atau janji lain yang akhirnya terselesaikan, maka .catch()
penangan dilewati. Namun, jika .then()
penangan melempar atau mengembalikan sebuah janji yang pada akhirnya menolak, maka .catch()
penangan akan mengeksekusi penolakan dalam janji asli p
, tetapi juga kesalahan yang terjadi pada .then()
penangan.
Dalam skema kedua, saat p
diselesaikan, .then()
penangan dipanggil. Jika .then()
penangan tersebut melempar atau mengembalikan sebuah janji yang pada akhirnya ditolak, maka .catch()
penangan tidak dapat menangkapnya karena itu sebelum itu dalam rantai.
Jadi, itulah perbedaan # 1. Jika .catch()
pawang AFTER, maka itu juga bisa menangkap kesalahan di dalam .then()
pawang.
Apa yang terjadi jika p
ditolak:
Sekarang, pada skema pertama, jika promise p
ditolak, maka .then()
handler dilewati dan .catch()
handler akan dipanggil seperti yang Anda harapkan. Apa yang Anda lakukan di .catch()
pawang menentukan apa yang dikembalikan sebagai hasil akhir. Jika Anda baru saja mengembalikan nilai dari .catch()
penangan atau mengembalikan janji yang akhirnya terselesaikan, rantai janji akan beralih ke status terselesaikan karena Anda "menangani" kesalahan dan mengembalikan secara normal. Jika Anda membuang atau mengembalikan janji yang ditolak di .catch()
pawang, janji yang dikembalikan tetap ditolak.
Pada skema kedua, jika promise p
ditolak, maka .catch()
handler dipanggil. Jika Anda mengembalikan nilai normal atau janji yang pada akhirnya .catch()
diselesaikan dari penangan (dengan demikian "menangani" kesalahan), maka rantai janji beralih ke keadaan terselesaikan dan .then()
penangan setelah .catch()
akan dipanggil.
Jadi itulah perbedaan # 2. Jika .catch()
penangannya SEBELUM, maka ia dapat menangani kesalahan dan memungkinkan .then()
penangan untuk tetap dipanggil.
Kapan menggunakan yang:
Gunakan skema pertama jika Anda menginginkan hanya satu .catch()
penangan yang dapat menangkap kesalahan baik di promise asli p
atau di .then()
penangan dan penolakan dari p
harus melewati .then()
penangan.
Gunakan skema kedua jika Anda ingin dapat menangkap error dalam promise asli p
dan mungkin (bergantung pada kondisi), izinkan rantai promise untuk dilanjutkan setelah diselesaikan, sehingga menjalankan .then()
penangan.
Pilihan lainnya
Ada satu opsi lain untuk menggunakan kedua callback yang dapat Anda teruskan .then()
seperti:
p.then(fn1, fn2)
Ini menjamin bahwa hanya satu dari fn1
atau fn2
akan pernah dipanggil. Jika berhasil p
, maka fn1
akan dipanggil. Jika p
ditolak, maka fn2
akan dipanggil. Tidak ada perubahan hasil yang fn1
dapat membuat fn2
dipanggil atau sebaliknya. Jadi, jika Anda ingin benar-benar memastikan bahwa hanya satu dari dua penangan Anda yang dipanggil terlepas dari apa yang terjadi pada penangan itu sendiri, maka Anda dapat menggunakan p.then(fn1, fn2)
.