Terdapat sedikit heboh hari ini tentang cadangan baharu untuk pengendali tugasan selamat (?=) dalam JavaScript. Saya suka bagaimana JavaScript telah bertambah baik dari semasa ke semasa, tetapi ini juga merupakan masalah yang saya hadapi dalam beberapa kes kebelakangan ini. Saya harus menyiapkan contoh pelaksanaan pantas sebagai fungsi, bukan?
Sekiranya anda belum membaca cadangan itu, berikut ialah cadangannya:
const [error, value] ?= maybeThrows();
Pengendali ?= baharu akan bersamaan dengan memanggil sebelah kanan tugasan dalam blok cuba/tangkap, mengembalikan tatasusunan. Nilai pertama tatasusunan yang dikembalikan akan menjadi ralat jika sesuatu dilemparkan ke dalam tugasan, dan nilai kedua akan menjadi hasil tugasan jika tiada yang dilemparkan.
Saya kerap terjumpa kod yang agak jelek di sekitar tugasan dan cuba/tangkap blok. Perkara seperti ini:
let errorMsg; try { maybeThrow(); } catch (e) { errorMsg = "An error message"; }
Untuk mengakses errorMsg di luar blok try/catch menggunakan const atau biarkan anda perlu mentakrifkannya di luar blok.
Kes paling mudah di sini ialah mengendalikan fungsi bukan async. Saya dapat menyebat
beberapa kes ujian dan fungsi yang dipanggil tryCatch dalam masa yang singkat:
function tryCatch(fn, ...args) { try { return [undefined, fn.apply(null, args)] } catch (e) { return [e, undefined]; } } function throws() { throw new Error("It threw"); } // returns a sum // prints [ undefined, 2 ] console.log(tryCatch(Math.sqrt, 4)); // returns an error // prints [ Error: 'It threw', undefined ] console.log(tryCatch(throws));
tryCatch memanggil fungsi dengan argumen yang diberikan dibalut dalam blok cuba/tangkap. Ia mengembalikan [undefined, result] dengan sewajarnya jika tiada apa-apa yang melempar ke dalam fungsi dan [error, undefined] jika sesuatu melempar.
Perhatikan bahawa anda boleh menggunakan fungsi tanpa nama dengan tryCatch juga jika anda belum mempunyai fungsi yang sedia untuk dipanggil.
console.log(tryCatch(() => { throw new Error("It threw"); }));
Fungsi async menjadi lebih rumit. Satu idea yang saya ada pada mulanya ialah menulis
versi async sepenuhnya, mungkin dipanggil asyncTryCatch, tetapi di manakah cabarannya. Ini adalah penerokaan yang sia-sia! Berikut ialah pelaksanaan tryCatch yang berfungsi dengan kedua-dua fungsi async dan bukan async:
function tryCatch(fn, ...args) { try { const result = fn.apply(null, args); if (result.then) { return new Promise(resolve => { result .then(v => resolve([undefined, v])) .catch(e => resolve([e, undefined])) }); } return [undefined, result]; } catch (e) { return [e, undefined]; } } function throws() { throw new Error("It threw"); } async function asyncSum(first, second) { return first + second; } async function asyncThrows() { throw new Error("It throws async"); } // returns a sum // prints [ undefined, 2 ] console.log(tryCatch(Math.sqrt, 4)); // returns an error // prints [ Error: 'It threw', undefined ] console.log(tryCatch(throws)); // returns a promise resolving to value // prints [ undefined, 3 ] console.log(await tryCatch(asyncSum, 1, 2)); // returns a promise resolving to error // prints [ Error: 'It throws async', undefined ] console.log(await tryCatch(asyncThrows));
Ia kelihatan sama seperti versi asal, tetapi dengan beberapa kod berasaskan Promise
dilemparkan untuk ukuran yang baik. Dengan pelaksanaan ini, anda boleh memanggil tryCatch apabila memanggil fungsi bukan async, dan kemudian memanggil menunggu tryCatch apabila memanggil fungsi async.
Jom lihat sedikit Janji:
if (result.then) { return new Promise(resolve => { result .then(v => resolve([undefined, v])) .catch(e => resolve([e, undefined])) }); }
jika (hasil.maka) menyemak sama ada fungsi yang diberikan (dipanggil dengan memohon) mengembalikan Janji. Jika ia berlaku, kita perlu memulangkan Janji sendiri.
Memanggil result.then(v => resolve([undefined, v])) menyebabkan janji menyelesaikan kepada nilai fungsi yang diberikan dikembalikan, jika tiada apa yang dilemparkan.
.catch(e => resolve([e, undefined])) adalah lebih rumit. Saya pada asalnya menulis
ia sebagai .catch(e => reject([e, undefined])), tetapi itu menyebabkan ralat tidak ditangkap
untuk keluar dari tryCatch. Kami perlu menyelesaikan di sini kerana kami memulangkan
tatasusunan, bukan membuang ralat.
Saya agak kerap mempunyai kes di mana saya perlu mencuba/menangkap tetapi berasa seperti
blok cubaan/tangkap eksplisit memakan banyak ruang dan menjengkelkan untuk tugasan skop. Saya tidak pasti sama ada saya akan menggunakannya atau tidak, tetapi ini adalah penerokaan kecil yang menyeronokkan.
Atas ialah kandungan terperinci Tugasan Selamat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!