coba {} tanpa menangkap {} mungkin dalam JavaScript?

114

Saya memiliki sejumlah fungsi yang mengembalikan sesuatu atau membuat kesalahan. Dalam fungsi utama, saya memanggil masing-masing ini, dan ingin mengembalikan nilai yang dikembalikan oleh setiap fungsi, atau melanjutkan ke fungsi kedua jika fungsi pertama memberikan kesalahan.

Jadi pada dasarnya apa yang saya miliki saat ini adalah:

function testAll() {
    try { return func1(); } catch(e) {}
    try { return func2(); } catch(e) {} // If func1 throws error, try func2
    try { return func3(); } catch(e) {} // If func2 throws error, try func3
}

Tetapi sebenarnya saya hanya tryingin mengembalikannya (yaitu jika tidak menimbulkan kesalahan). Saya tidak butuh catchblok. Namun, kode suka try {}gagal karena tidak memiliki catch {}blok (tidak digunakan) .

Saya memberi contoh di jsFiddle .

Jadi, adakah cara untuk catchmenghilangkan blok - blok itu sambil mencapai efek yang sama?

pimvdb.dll
sumber

Jawaban:

4

Tidak. Anda harus menyimpannya.

Ini sebenarnya masuk akal karena kesalahan tidak boleh diabaikan sama sekali.

ThiefMaster
sumber
16
Dalam hal ini, fungsi tersebut tidak boleh menampilkan kesalahan tetapi mengembalikan misalnya nulldan Anda melakukan sesuatu sepertireturn func1() || func2() || func3();
ThiefMaster
53
Jawaban ini salah secara faktual, Anda dapat memiliki try {}; finally {}seperti yang ditunjukkan di stackoverflow.com/a/5764505/68210
Daniel X Moore
4
@DanielXMoore, tanpa catch (e) {}, pengecualian yang diberikan func1()akan mencegah func2()dari dicoba.
binki
66
Terkadang masuk akal untuk memiliki tangkapan kosong, jadi saya tidak setuju dengan argumen Anda.
Petr Peller
8
Jawaban ini salah secara faktual dan menyesatkan. "Sebenarnya masuk akal" Anda berkata, tetapi Anda salah, itu hanya masuk akal dalam beberapa kasus dan tidak pada yang lain. Ini adalah contoh yang bagus dari jawaban buruk yang diterima secara tidak dapat dijelaskan. Ada banyak kasus di mana masuk akal untuk tidak memiliki blok penangkap, seperti dalam suatu asyncfungsi, terkadang. Dipaksa oleh bahasa javascript untuk membuat catchblok kosong jelas tidak ada gunanya.
YungGun
236

Sebuah percobaan tanpa klausa menangkap mengirimkan kesalahannya ke tangkapan yang lebih tinggi berikutnya , atau jendela, jika tidak ada tangkapan yang ditentukan dalam percobaan itu.

Jika Anda tidak mengerti , ekspresi percobaan membutuhkan klausa akhirnya .

try {
    // whatever;
} finally {
    // always runs
}
kennebec
sumber
Jadi, cara terbaik adalah menulis sesuatu seperti try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { //always run}}}?
pengguna2284570
1
Komentar di atas tidak menjawab OP secara akurat karena dia tidak ingin menjalankan fungsi 2 jika fungsi 1 berhasil.
Andrew Steitz
2
Perhatikan bahwa percobaan tanpa tangkapan tidak menelan kesalahan .
Dan Dascalescu
Terima kasih, itulah yang saya butuhkan :-) Akan sangat luar biasa jika ini juga berfungsi tanpa mencoba {} Maksud saya: async () => {indicWorkInProgress () await pipelineStep1 () await pipelineStep2 () ... akhirnya {stopIndicator ( )}} Akan jelas bahwa seluruh fungsi dimaksudkan ;-) Blok percobaan itu sangat jelek di sana ...
Lenny
35

Mungkin saja memiliki blok catch kosong, tanpa variabel error, dimulai dengan ES2019 . Ini disebut pengikatan tangkapan opsional dan diterapkan di V8 v6.6, dirilis pada Juni 2018 . Fitur tersebut telah tersedia sejak Node 10 , Chrome 66 , Firefox 58 , Opera 53 dan Safari 11.1 .

Sintaksnya ditampilkan di bawah ini:

try {
  throw new Error("This won't show anything");
} catch { };

Anda masih memerlukan catchblok, tetapi blok itu bisa kosong dan Anda tidak perlu meneruskan variabel apa pun. Jika Anda tidak menginginkan blok tangkapan sama sekali, Anda dapat menggunakan try/ finally, tetapi perhatikan bahwa itu tidak akan menelan kesalahan seperti halnya tangkapan kosong.

try {
  throw new Error("This WILL get logged");
} finally {
  console.log("This syntax does not swallow errors");
}

Dan Dascalescu
sumber
2
jawaban ini paling mutakhir! dalam hal urutan eksekusi, 1. mencoba trymemblokir. 2. Menangkap kesalahan. 3. Jalankan finallyblok. 4. Melempar kesalahan. Apakah ini benar?
helsont
Terima kasih @helsont. Adapun urutan eksekusi dalam contoh kode kedua, saya tidak yakin seseorang dapat mengetahui apakah kesalahan ditangkap dan dilemparkan kembali, atau hanya (mungkin) hanya dilempar dan tidak tertangkap di tempat pertama (karena tidak ada catch). Kelilingi seluruh kode dengan try/ yang laincatch dan Anda akan dapat menemukan This WILL get loggedkesalahannya.
Dan Dascalescu
Tampak sangat bersih sekarang. Terima kasih telah berbagi!
LeOn - Han Li
10

Tidak, catch(atau finally) adalah tryteman dan selalu ada sebagai bagian dari coba / tangkap .

Namun, sangat valid untuk mengosongkannya, seperti dalam contoh Anda.

Dalam komentar di kode contoh Anda ( Jika func1 melempar kesalahan, coba func2 ), tampaknya yang benar-benar ingin Anda lakukan adalah memanggil fungsi selanjutnya di dalam catchblok sebelumnya.

alex
sumber
1
Kamu benar. Namun jika kode seperti try {...}; try {...}itu dimungkinkan, arti kode mungkin lebih jelas (coba yang pertama, jika tidak coba yang kedua).
pimvdb
Tentang edit Anda: Dalam contoh JSFiddle, fungsi kedua mengembalikan sesuatu, jadi apakah fungsi ketiga benar-benar dievaluasi dalam kasus itu? Saya pikir sebuah returnpernyataan menghentikan apa pun yang datang setelahnya.
pimvdb
@pimvdb Maaf, saya tidak memeriksa biola. returnakan menyebabkan fungsi kembali sebelum waktunya. Saya akan memperbarui jawaban saya.
alex
1
Jawaban ini salah secara faktual, Anda dapat memiliki try {}; finally {}seperti yang ditunjukkan di stackoverflow.com/a/5764505/68210
Daniel X Moore
1
@DanielXMoore Tentu saja, tetapi finally{}pada dasarnya memiliki semangat yang sama dengan catch{}. Saya akan memperbarui jawabannya.
alex
6

Saya tidak akan merekomendasikan coba-akhirnya tanpa tangkapan, karena jika kedua blok percobaan dan akhirnya kesalahan lemparan blok, kesalahan yang dilemparkan pada klausa akhirnya menggelembung dan kesalahan blok percobaan diabaikan, dalam pengujian saya sendiri:

try {
  console.log('about to error, guys!');
  throw new Error('eat me!');
} finally {
  console.log ('finally, who cares');
  throw new Error('finally error');
}

Hasil:

>     about to error, guys!
>     finally, who cares
>     .../error.js:9
>         throw new Error('finally error');
>         ^
>     
>     Error: finally error
Joe B.
sumber
1

Mereka bekerja sama dalam setiap bahasa yang saya tahu yang memilikinya (JavaScript, Java, C #, C ++). Jangan lakukan itu.

duffymo
sumber
1
Aneh bahwa jawaban saya diturunkan lima tahun kemudian ketika dikatakan hal yang sama dengan jawaban lain di sini. Milik saya tampaknya satu-satunya yang mendapat suara negatif. Moderator, harap perhatikan.
duffymo
Tcl memiliki konstruksi kata tunggal yang sangat nyamancatch {my code}
MKaama
Mengapa? Terasa tidak berguna, kecuali dicoba / akhirnya.
duffymo
1

Saya telah memutuskan untuk melihat masalah yang disajikan dari sudut pandang yang berbeda.

Saya telah dapat menentukan cara untuk memperbolehkan dengan dekat pola kode yang diminta sementara sebagian menangani objek kesalahan yang tidak ditangani yang terdaftar oleh pemberi komentar lain.

kode bisa dilihat di @ http://jsfiddle.net/Abyssoft/RC7Nw/4/

try: catch ditempatkan dalam loop for yang memungkinkan jatuh dengan anggun. sekaligus dapat melakukan iterasi melalui semua fungsi yang dibutuhkan. ketika penanganan kesalahan eksplisit diperlukan, larik fungsi tambahan digunakan. di genap kesalahan dan array fungsional dengan elemen penanganan kesalahan bukan fungsi, kesalahan dibuang ke konsol.

Sesuai persyaratan stackoverflow di sini adalah kode sebaris [diedit agar sesuai dengan JSLint (hapus spasi di depan untuk mengonfirmasi), meningkatkan keterbacaan]

function func1() {"use strict"; throw "I don't return anything"; }
function func2() {"use strict"; return 123; }
function func3() {"use strict"; throw "I don't return anything"; }

// ctr = Code to Run <array>, values = values <array>, 
// eh = error code can be blank.
// ctr and params should match 1 <-> 1
// Data validation not done here simple POC
function testAll(ctr, values, eh) {
    "use strict";
    var cb; // cb = code block counter
    for (cb in ctr) {
        if (ctr.hasOwnProperty(cb)) {
            try {
                return ctr[cb](values[cb]);
            } catch (e) {
                if (typeof eh[cb] === "function") {
                    eh[cb](e);
                } else {
                    //error intentionally/accidentially ignored
                    console.log(e);
                }
            }
        }
    }
    return false;
}

window.alert(testAll([func1, func2, func3], [], []));

</s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> orang </s>

pengguna1800957
sumber
1

Jika Anda hanya ingin fungsi 2 dan 3 diaktifkan jika terjadi kesalahan mengapa Anda tidak menempatkannya di blok catch?

function testAll() {
  try {
    return func1();
  } catch(e) {
    try {
      return func2();
    } catch(e) {
      try {
        return func3();
      } catch(e) {
        // LOG EVERYTHING FAILED
      }
    }
  }
}
Tangki
sumber
0

Saya yakin Anda perlu menggunakan fungsi helper seperti:

function tryIt(fn, ...args) {
    try {
        return fn(...args);
    } catch {}
}

dan gunakan seperti:

tryIt(function1, /* args if any */);
tryIt(function2, /* args if any */);
Itay Merchav
sumber
-2

Sejak ES2019 Anda dapat dengan mudah menggunakan try {}tanpa catch {}:

try {
  parseResult = JSON.parse(potentiallyMalformedJSON);
} catch (unused) {}

Untuk info lebih lanjut silakan merujuk ke proposal Michael Ficcara

JamesJGoodwin
sumber
1
Tidak, catchmasih diperlukan, hanya pengikatan yang tidak diperlukan ...
chipit24