Saya telah membaca beberapa artikel tentang hal ini, tetapi masih belum jelas bagi saya jika ada perbedaan antara Promise.reject
vs melempar kesalahan. Sebagai contoh,
Menggunakan Promise.reject
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
return Promise.reject(new PermissionDenied());
}
});
Menggunakan lemparan
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
throw new PermissionDenied();
}
});
Preferensi saya adalah menggunakan throw
hanya karena lebih pendek, tetapi bertanya-tanya apakah ada kelebihan satu di atas yang lain.
javascript
promise
Naresh
sumber
sumber
.then()
handler menangkap pengecualian dilemparkan dan mengubahnya menjadi sebuah janji ditolak secara otomatis. Karena saya telah membaca bahwa pengecualian yang dilemparkan tidak terlalu cepat untuk dieksekusi, saya akan menduga bahwa mengembalikan janji yang ditolak mungkin sedikit lebih cepat untuk dieksekusi, tetapi Anda harus merancang tes di beberapa browser modern jika itu penting untuk diketahui. Saya pribadi menggunakanthrow
karena saya suka keterbacaan.throw
adalah bahwa itu tidak akan menghasilkan janji yang ditolak jika dilempar dari dalam panggilan balik yang tidak sinkron, seperti setTimeout. jsfiddle.net/m07van33 @Blondie jawaban Anda benar.reject
dari daftar param saya.Jawaban:
Tidak ada keuntungan menggunakan satu vs yang lain, tetapi, ada kasus khusus di mana
throw
tidak akan berfungsi. Namun, kasus-kasus itu dapat diperbaiki.Setiap kali Anda berada dalam janji panggilan balik, Anda dapat menggunakan
throw
. Namun, jika Anda menggunakan panggilan balik asinkron lainnya, Anda harus menggunakannyareject
.Misalnya, ini tidak akan memicu tangkapan:
Alih-alih, Anda pergi dengan janji yang tidak terselesaikan dan pengecualian yang tidak tertangkap. Itu adalah kasus di mana Anda ingin menggunakannya
reject
. Namun, Anda bisa memperbaikinya dengan dua cara.sumber
throw error
, Anda juga tidak dapat menggunakanreturn Promise.reject(err)
apa yang diminta OP untuk dibandingkan. Ini pada dasarnya mengapa Anda tidak harus memasukkan callback async ke dalam janji. Promisikan semua yang async dan kemudian Anda tidak memiliki batasan ini.Array#forEach
) dan dengan itu, melempar ke dalamnya akan berhasil.throw
tidak akan berfungsi dan sebagai gantinyaPromise.reject
adalah pilihan yang lebih baik. Namun cuplikan tidak terpengaruh dengan salah satu dari dua pilihan tersebut dan memberikan hasil yang sama terlepas dari apa yang Anda pilih. Apakah saya melewatkan sesuatu?reject
yang diteruskan kenew Promise(fn)
panggilan balik.return Promise.reject()
danthrow
. Dia tidak menyebutkanreject
panggilan balik yang diberikan dalamnew Promise(function(resolve, reject))
konstruksi. Jadi sementara dua cuplikan Anda menunjukkan dengan tepat kapan Anda harus menggunakan panggilan balik tekad, pertanyaan OP bukan itu.Fakta penting lainnya adalah
reject()
JANGAN menghentikan aliran kontrol sepertireturn
pernyataan. Sebaliknyathrow
menghentikan aliran kontrol.Contoh:
vs.
sumber
return reject()
, sehingga baris berikutnya tidak akan berjalan.return reject()
hanya singkatan untukreject(); return
apa yang Anda inginkan adalah untuk menghentikan aliran. Nilai kembali dari pelaksana (fungsi dilewatkan kenew Promise
) tidak digunakan, jadi ini aman.Ya, perbedaan terbesar adalah bahwa menolak adalah fungsi panggilan balik yang dilakukan setelah janji ditolak, sedangkan melempar tidak dapat digunakan secara tidak sinkron. Jika Anda memilih untuk menggunakan tolak, kode Anda akan terus berjalan secara normal dalam mode asinkron saat melempar akan memprioritaskan menyelesaikan fungsi penyelesai (fungsi ini akan segera berjalan).
Contoh yang pernah saya lihat yang membantu mengklarifikasi masalah bagi saya adalah Anda dapat mengatur fungsi Timeout dengan tolak, misalnya:
Di atas tidak mungkin menulis dengan lemparan.
Dalam contoh kecil Anda perbedaan dalam dibedakan tetapi ketika berhadapan dengan konsep asinkron yang lebih rumit perbedaan antara keduanya bisa drastis.
sumber
TLDR: Suatu fungsi sulit untuk digunakan ketika kadang-kadang mengembalikan janji dan kadang-kadang melempar pengecualian. Saat menulis fungsi async, lebih suka memberi sinyal kegagalan dengan mengembalikan janji yang ditolak
Contoh khusus Anda mengaburkan beberapa perbedaan penting di antara mereka:
Karena Anda salah menangani di dalam rantai janji, pengecualian yang dilemparkan dapat dikonversi secara otomatis menjadi janji yang ditolak. Ini mungkin menjelaskan mengapa mereka tampaknya dapat dipertukarkan - tidak.
Pertimbangkan situasi di bawah ini:
Ini akan menjadi anti-pola karena Anda perlu mendukung kasus kesalahan async dan sinkronisasi. Itu mungkin terlihat seperti:
Tidak bagus dan di sinilah tempat
Promise.reject
(tersedia dalam lingkup global) untuk menyelamatkan dan secara efektif membedakan dirinyathrow
. Refactor sekarang menjadi:Ini sekarang memungkinkan Anda menggunakan hanya satu
catch()
untuk kegagalan jaringan dan pemeriksaan kesalahan sinkron untuk kekurangan token:sumber
Promise.reject
atauthrow
ketika Anda ingin mengembalikan janji yang ditolak (janji yang akan melompat ke yang berikutnya.catch()
).checkCredentials(x).then(onFulfilled).catch(e) {}
, dan memilikicatch
pegangan baik kotak penolakan maupun kotak kesalahan yang dilemparkan?Contoh untuk dicoba. Cukup ubah isVersionThrow to false untuk menggunakan tolak alih-alih membuang.
sumber