Kepentingan sentiasa menangkap kesilapan dalam Janji
P粉590929392
P粉590929392 2024-03-19 21:05:20
0
1
403

Saya menggunakan @typescript-eslint/no-floating-promises peraturan dalam projek saya. Jika saya menulis kod seperti ini, peraturan ini akan mengeluh -

functionReturningPromise()
    .then(retVal => doSomething(retVal));

Ia mahu saya untuk blok Promise 添加一个 catch ini. Ini masuk akal kepada saya jika saya ingin menambah beberapa logik dalam blok pengendalian pengecualian. Walau bagaimanapun, terdapat banyak situasi di mana saya tidak memerlukannya. Saya gembira dengan kesilapan yang dilemparkan. Jadi untuk menyekat ralat yang dilemparkan oleh peraturan ini, saya akhirnya melakukan ini -

functionReturningPromise()
    .then((retVal) => doSomething(retVal))
    .catch((error) => {
        throw error;
    });
Adakah ia benar-benar membuat perbezaan walaupun saya tidak menambah catch 块,error 仍然会以相同的方式抛出(至少在我的控制台输出中看到它)。因此,我不明白显式指定此 catch 块的意义。我错过了什么吗?如果我添加/不添加 catch 块,抛出 error seperti di atas?

P粉590929392
P粉590929392

membalas semua(1)
P粉106711425

Pengulas semuanya telah menjawab soalan anda dengan baik - tetapi untuk menggambarkan melalui contoh mengapa ini penting, bayangkan kod berikut:

Promise.reject();
setTimeout(() => console.log('hello'), 1000);

Kod ini kelihatan agak tidak berbahaya - terdapat penolakan janji tanpa operasi yang tidak dikendalikan bahawa program akan dilog 'hello' 1 saat selepas permulaan.

Dalam penyemak imbas - inilah yang akan berlaku - penyemak imbas akan merekodkan ralat "Penolakan Janji Tidak Ditangkap", tetapi sebaliknya mengabaikannya.

Walau bagaimanapun, dalam NodeJS (setakat Node v15), penolakan Promise yang tidak dikendalikan adalah ralat keras - bermakna proses akan keluar apabila ralat dikesan!

Anda boleh mengesahkan ini dengan menjalankan kod dalam Terminal (-e bermaksud "nilai dan jalankan rentetan kod ini")

$ node -e "Promise.reject(); setTimeout(() => console.log('hello'), 1000)"
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "undefined".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

Node.js v18.12.1

Anda boleh lihat 'hello' tidak pernah dicetak kerana proses ditamatkan sebelum 1 saat!

Untuk mengesahkan bahawa perkara berfungsi seperti yang diharapkan, anda boleh .reject 更改为 .resolve:

$ node -e "Promise.resolve(); setTimeout(() => console.log('hello'), 1000)"
hello

Jadi, jika anda menulis aplikasi NodeJS menggunakan mana-mana versi yang disokong LTS maka anda pasti perlu menangani ralat jika tidak, anda akan menghadapi risiko ranap yang tidak dijangka.

Jika kod anda hanya berjalan dalam penyemak imbas, anda mungkin tertanya-tanya sama ada anda perlu menangani kegagalan sama sekali - lagipun, pengguna anda tidak melihat konsol, jadi mereka tidak akan tahu apa-apa perkara buruk berlaku, jadi siapa peduli? Dari perspektif "kod sahaja", anda betul - walau bagaimanapun, pengguna anda mahukan maklum balas daripada aplikasi mereka apabila berlaku kesilapan.

Bayangkan senario berikut - Janji anda menjejaki keputusan panggilan API yang menyerahkan beberapa data yang dimasukkan oleh pengguna dalam aplikasi anda. Jika panggilan API gagal atas sebab tertentu, aplikasi anda harus bertindak balas dengan sewajarnya dan memberitahu pengguna sesuatu telah berlaku.

Cara alternatif untuk mengendalikannya mungkin bermakna apl anda memaparkan pemutar pemuatan yang tidak terhingga, atau pengguna berpendapat data mereka berjaya diserahkan sedangkan ia sebenarnya tidak. Sama ada cara - ini adalah pengalaman pengguna yang sangat teruk dan rosak!

Adalah lebih baik untuk melakukan sesuatu yang mudah seperti .catch(e => { throw e }) 这样的事情,你实际上并没有处理错误。当然,这段代码会使 linter 保持沉默 - 但您所做的只是创建一个新的、被拒绝的承诺,该承诺将记录到控制台。相反,您应该以某种方式将错误连接到应用程序的 UI,例如像 .catch(e => {alert(e); throw e }) akhirnya.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan