Saya telah melihat FAQ tentang burung bluebird , yang menyebutkan bahwa itu .then(success, fail)
adalah antipattern . Saya tidak begitu mengerti penjelasannya tentang mencoba dan menangkap. Apa yang salah dengan yang berikut ini?
some_promise_call()
.then(function(res) { logger.log(res) }, function(err) { logger.log(err) })
Tampaknya contoh ini menyarankan yang berikut ini sebagai cara yang benar.
some_promise_call()
.then(function(res) { logger.log(res) })
.catch(function(err) { logger.log(err) })
Apa bedanya?
javascript
node.js
promise
bluebird
pengguna2127480
sumber
sumber
then().catch()
lebih mudah dibaca, karena Anda tidak perlu mencari koma dan menyelidiki apakah panggilan balik ini untuk cabang sukses atau gagal..catch
, Anda tidak tahu langkah mana yang menyebabkan masalah - di dalam yang terakhirthen
atau di tempat lain di rantai janji. Jadi memang memiliki kekurangannya sendiri.some_promise_call() .then(function fulfilled(res) { logger.log(res) }, function rejected(err) { logger.log(err) })
Jawaban:
The
.then()
panggilan akan kembali janji yang akan ditolak dalam kasus panggil balik melempar kesalahan. Ini berarti, ketika kesuksesan Andalogger
gagal, kesalahan akan diteruskan ke.catch()
callback berikut , tetapi tidak kefail
callback yang menyertainyasuccess
.Berikut diagram alir kontrol :
Untuk mengekspresikannya dalam kode sinkron:
Yang kedua
log
(yang seperti argumen pertama.then()
) hanya akan dieksekusi jika tidak ada pengecualian yang terjadi. Blok berlabel danbreak
pernyataan merasa sedikit aneh, ini sebenarnya apa python memilikitry-except-else
untuk (membaca direkomendasikan!).The
catch
logger juga akan menangani pengecualian dari panggilan sukses logger.Begitu banyak perbedaannya.
Argumennya adalah bahwa biasanya Anda ingin menangkap kesalahan di setiap langkah pemrosesan, dan Anda tidak boleh menggunakannya dalam rantai. Harapannya adalah bahwa Anda hanya memiliki satu penangan akhir yang menangani semua kesalahan - sementara, ketika Anda menggunakan "antipattern", kesalahan dalam beberapa panggilan balik saat itu tidak ditangani.
Namun, pola ini sebenarnya sangat berguna: Ketika Anda ingin menangani kesalahan yang terjadi pada langkah ini, dan Anda ingin melakukan sesuatu yang sama sekali berbeda ketika tidak ada kesalahan terjadi - yaitu ketika kesalahan tidak dapat dipulihkan. Ketahuilah bahwa ini adalah percabangan aliran kendali Anda. Tentu saja, ini kadang diinginkan.
Bahwa Anda harus mengulangi panggilan balik Anda. Anda lebih suka
Anda juga dapat mempertimbangkan
.finally()
untuk menggunakan ini.sumber
.catch
akan menangkap kesalahan bahkan di dalam fungsi sukses .. Secara pribadi, saya menemukan ini sangat salah karena Anda berakhir dengan satu titik masuk kesalahan, yang bisa mendapatkan banyak kesalahan dari beberapa tindakan, tapi ini masalah saya. Bagaimanapun - terima kasih untuk informasinya! Apakah Anda tidak memiliki alat komunikasi online yang ingin Anda bagikan sehingga saya dapat menanyakan beberapa hal lagi? : PPromise
mekanik penting di situs ini..done()
bukan bagian dari standar, kan? Setidaknya MDN tidak mencantumkan metode itu. Itu akan sangat membantu.done
adalah hal Bluebird yang pada dasarnya usang olehthen
deteksi + unhandled-rejection.Keduanya tidak identik. Perbedaannya adalah bahwa contoh pertama tidak akan menangkap pengecualian yang ada pada
success
handler Anda . Jadi, jika metode Anda hanya akan mengembalikan janji yang telah diselesaikan, seperti yang sering terjadi, Anda memerlukan trailingcatch
handler (atau yang lainnyathen
dengansuccess
parameter kosong ). Tentu, mungkinthen
handler Anda tidak melakukan apa pun yang berpotensi gagal, dalam hal ini menggunakan satu 2 parameterthen
bisa baik-baik saja.Tapi saya percaya inti dari teks yang Anda tautkan adalah yang
then
sebagian besar bermanfaat dibandingkan dengan panggilan balik dalam kemampuannya untuk mengaitkan beberapa langkah asinkron, dan ketika Anda benar-benar melakukan ini, bentuk 2-parameter darithen
subtly tidak berperilaku cukup seperti yang diharapkan , untuk alasan di atas. Ini terutama berlawanan dengan intuisi ketika digunakan rantai tengah.Sebagai seseorang yang telah melakukan banyak hal async yang kompleks dan menabrak sudut-sudut seperti ini lebih dari yang saya akui, saya sangat merekomendasikan menghindari anti-pola ini dan menggunakan pendekatan penangan yang terpisah.
sumber
Dengan melihat kelebihan dan kekurangan dari keduanya, kita dapat membuat perkiraan yang tepat untuk situasi yang tepat. Ini adalah dua pendekatan utama untuk mengimplementasikan janji-janji. Keduanya memiliki kelebihan dan kekurangan
Keuntungan
Kekurangan
Keuntungan
Kerugian
catch
jika Anda ingin menangani kesalahan yang dilemparkan oleh keberhasilan panggilan baliksumber
Penjelasan sederhana:
Dalam ES2018
itu berarti:
sama dengan
sumber
Menggunakan
.then().catch()
memungkinkan Anda mengaktifkan Promise Chaining yang diperlukan untuk memenuhi alur kerja. Anda mungkin perlu membaca beberapa informasi dari database kemudian Anda ingin meneruskannya ke API async kemudian Anda ingin memanipulasi respons. Anda mungkin ingin mendorong respons kembali ke database. Menangani semua alur kerja ini dengan konsep Anda bisa dilakukan tetapi sangat sulit untuk dikelola. Solusi yang lebih baik adalahthen().then().then().then().catch()
menerima semua kesalahan hanya dalam sekali penangkapan dan memungkinkan Anda menjaga kelestarian kode.sumber
Menggunakan
then()
dancatch()
membantu rantai kesuksesan dan kegagalan penangan pada janji.catch()
bekerja dengan janji dikembalikan olehthen()
. Itu menangani,then()
tidak menangani hal ini.)1. let promiseRef: Promise = this. aTimetakingTask (false); 2. promiseRef 3. .then( 4. (result) => { 5. /* successfully, resolved promise. 6. Work on data here */ 7. }, 8. (error) => console.log(error) 9. ) 10. .catch( (e) => { 11. /* successfully, resolved promise. 12. Work on data here */ 13. });
Masuk akal karena janji yang dikembalikan oleh
then()
tidak memiliki kesalahan jika panggilan balik menanganinya.sumber
catch
panggilan balik tampak salah.Alih-alih kata-kata, contoh yang bagus. Kode berikut (jika janji pertama terselesaikan):
identik dengan:
Tetapi dengan janji pertama yang ditolak, ini tidak identik:
sumber