Bagaimana saya bisa menolak janji yang dikembalikan oleh fungsi async / menunggu?
misalnya asalnya
foo(id: string): Promise<A> {
return new Promise((resolve, reject) => {
someAsyncPromise().then((value)=>resolve(200)).catch((err)=>reject(400))
});
}
Terjemahkan ke async / tunggu
async foo(id: string): Promise<A> {
try{
await someAsyncPromise();
return 200;
} catch(error) {//here goes if someAsyncPromise() rejected}
return 400; //this will result in a resolved promise.
});
}
Jadi, bagaimana saya bisa menolak janji ini dalam kasus ini?
Promise
antipattern konstruktor ! Bahkan cuplikan pertama seharusnya ditulisfoo(id: string): Promise<A> { return someAsyncPromise().then(()=>{ return 200; }, ()=>{ throw 400; }); }
Jawaban:
Anda bertaruh terbaik adalah untuk
throw
sebuahError
pembungkus nilai, yang menghasilkan janji menolak denganError
pembungkus nilai:Anda juga bisa hanya
throw
nilainya, tetapi kemudian tidak ada informasi jejak tumpukan:Bergantian, kembalikan janji yang ditolak dengan nilai
Error
pembungkus, tetapi itu tidak idiomatis:(Atau hanya
return Promise.reject(400);
, tapi sekali lagi, maka tidak ada informasi konteks.)(Dalam kasus Anda, saat Anda menggunakan
TypeScript
danfoo
nilainya kembaliPromise<A>
, Anda akan menggunakanreturn Promise.reject<A>(400 /*or error*/);
)Dalam suatu
async
/await
situasi, yang terakhir itu mungkin sedikit salah pertandingan semantik, tetapi itu berhasil.Jika Anda melempar
Error
, itu cocok dengan apa pun yang mengonsumsifoo
hasil Anda denganawait
sintaks:sumber
throw
lebih baik daripadaPromise.reject()
IMO. Apakah akanthrow 400
merupakan pertanyaan yang berbeda. Dalam OP itu menolak 400, dan kita bisa berargumen bahwa itu harus menolakError
sebaliknya.async
fungsi, tidak adaresolve
ataureject
fungsi. Adareturn
danthrow
, yang merupakan cara idiomatis untuk menyelesaikan dan menolakasync
janji fungsi.new
buat itu eksplisit. Perhatikan juga bahwa Anda tidak dapat meninggalkannya jika memilikiError
subclass (class MyError extends Error
), jadi ...Mungkin juga harus disebutkan bahwa Anda hanya dapat rantai
catch()
fungsi setelah panggilan operasi async Anda karena di bawah tenda masih ada janji yang dikembalikan.Dengan cara ini Anda dapat menghindari
try/catch
sintaksis jika Anda tidak menyukainya.sumber
async
fungsi saya , saya membuang pengecualian dan kemudian menangkapnya dengan baik.catch()
seperti jika saya kembaliPromise.reject
atau meneleponreject
. Saya suka itu!await
kegagalan dalam satu rutin. Kecuali jika dibutuhkan kasus yang sangat spesifik untuk masing-masing,await
saya tidak mengerti mengapa Anda ingin menangkapnya seperti ini. Hanya saya pendapat yang rendah hati.await
kegagalan secara terpisah, tetapi saya juga perlu bekerja dengan kerangka kerja berbasis Janji yang menolak janji kesalahan.${host}/user/permissions/repositories_wrong_url/
, accessToken, accessTokenSecret) .catch (err => {logger.error ('Tidak dapat mengambil izin repositori', err); callback (err);})await
kata kunci di sini.Anda bisa membuat fungsi wrapper yang menerima janji dan mengembalikan array dengan data jika tidak ada kesalahan dan kesalahan jika ada kesalahan.
Gunakan seperti ini di ES7 dan dalam fungsi async :
sumber
Cara yang lebih baik untuk menulis fungsi async adalah dengan mengembalikan Janji yang tertunda sejak awal dan kemudian menangani penolakan dan resolusi dalam panggilan balik janji tersebut, daripada hanya memuntahkan janji yang ditolak karena kesalahan. Contoh:
Maka Anda hanya rantai metode pada janji yang dikembalikan:
Sumber - tutorial ini:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
sumber
Saya punya saran untuk menangani dengan benar penolakan dalam pendekatan baru, tanpa memiliki beberapa blok uji coba.
Di mana fungsi to.ts harus diimpor dari:
Kredit masuk ke Dima Grossman di tautan berikut .
sumber
let [err]=
jika hanya memeriksa kesalahan.Ini bukan jawaban atas @TJ Crowder. Hanya komentar menanggapi komentar "Dan sebenarnya, jika pengecualian akan dikonversi menjadi penolakan, saya tidak yakin apakah saya benar-benar terganggu jika itu adalah Kesalahan. Alasan saya untuk melemparkan hanya Kesalahan mungkin tidak berlaku. "
jika kode Anda menggunakan
async
/await
, maka masih merupakan praktik yang baik untuk menolak denganError
alih - alih400
:sumber
Saya tahu ini adalah pertanyaan lama, tapi saya baru saja menemukan benang merah dan tampaknya ada perselisihan di sini antara kesalahan dan penolakan yang berjalan bertentangan (dalam banyak kasus, setidaknya) dari saran yang sering diulangi untuk tidak menggunakan penanganan pengecualian untuk menangani kasus yang diantisipasi. Sebagai ilustrasi: jika metode async mencoba untuk mengotentikasi pengguna dan otentikasi gagal, itu adalah penolakan (salah satu dari dua kasus yang diantisipasi) dan bukan kesalahan (misalnya, jika API otentikasi tidak tersedia.)
Untuk memastikan saya tidak hanya membelah rambut, saya menjalankan tes kinerja tiga pendekatan berbeda untuk itu, menggunakan kode ini:
Beberapa hal yang ada di sana dimasukkan karena ketidakpastian saya tentang penerjemah Javascript (saya hanya ingin turun satu lubang kelinci pada suatu waktu); misalnya, saya memasukkan
doSomething
fungsi dan mengembalikannyadummyValue
untuk memastikan bahwa blok bersyarat tidak akan dioptimalkan.Hasil saya adalah:
Saya tahu bahwa ada banyak kasus di mana tidak ada masalah dengan memburu optimasi kecil, tetapi dalam sistem skala yang lebih besar hal-hal ini dapat membuat perbedaan kumulatif yang besar, dan itu perbandingan yang sangat mencolok.
SO ... sementara saya pikir pendekatan jawaban yang diterima adalah suara dalam kasus di mana Anda berharap harus menangani kesalahan tak terduga dalam fungsi async, dalam kasus di mana penolakan hanya berarti "Anda harus pergi dengan Plan B (atau C, atau D ...) "Saya pikir preferensi saya adalah menolak menggunakan objek respons khusus.
sumber