JavaScript'te {} catch olmadan {} deneyin mümkün mü?


114

Bir şey döndüren veya bir hata atan bir dizi işlevim var. Bir ana işlevde, bunların her birini çağırırım ve her işlevin döndürdüğü değeri döndürmek veya ilk işlev bir hata atarsa ​​ikinci işleve geçmek isterim.

Yani temelde şu anda sahip olduğum şey:

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
}

Ama aslında sadece tryonu iade etmek istiyorum (yani bir hata oluşturmazsa). Bloğa ihtiyacım yok catch. Ancak, try {}(kullanılmayan) bir catch {}bloğu eksik olduğu için kod gibi başarısız olur .

Ben koymak jsFiddle üzerinde bir örnek .

Peki, catchaynı etkiyi elde ederken bu blokları kaldırmanın bir yolu var mı?

Yanıtlar:


4

Hayır. Onları saklamalısın.

Hataların sessizce göz ardı edilmemesi gerektiğinden bu aslında mantıklı.


16
Bu durumda, bu işlevler hata vermemeli, örneğin geri dönmelidir nullve şöyle bir şey yaparsınızreturn func1() || func2() || func3();
ThiefMaster

53
Bu cevap, sen dayanarak yanlış olması olabilir edilir try {}; finally {}olarak gösterilen stackoverflow.com/a/5764505/68210
Daniel X Moore'a

4
@DanielXMoore, catch (e) {}tarafından atılan istisna olmadan yargılanmayı func1()engeller func2().
binki

66
Bazen boş bir yakalamaya sahip olmak çok mantıklı geliyor, bu yüzden argümanınıza katılmıyorum.
Petr Peller

8
Bu cevap gerçeklere dayalı olarak yanlış ve yanıltıcıdır. "Aslında mantıklı" diyorsunuz, ama yanılıyorsunuz, sadece bazı durumlarda mantıklı geliyor, bazılarında değil. Açıklanamaz bir şekilde kabul edilen korkunç bir cevabın harika bir örneğidir. asyncBazen bir işlevde olduğu gibi catch bloğunun olmamasının mantıklı olduğu birçok durum vardır . Javascript dili tarafından boş catchbloklar oluşturmaya zorlanmak açıkça anlamsız.
YungGun

236

Bir deneyin bir olmadan yakalamak fıkra sonraki daha yüksek olan hatayı gönderir yakalama o denemede içinde tanımlanmış hiçbir yakalamak varsa, veya pencere.

Eğer bir catchiniz yoksa , try ifadesi bir last cümlesi gerektirir .

try {
    // whatever;
} finally {
    // always runs
}

Öyleyse en iyi yol şöyle bir şey yazmaktır try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { //always run}}}?
user2284570

1
Yukarıdaki açıklama OP'yi doğru yanıtlamaz çünkü eğer 1. işlev başarılı olursa 2. işlevi çalıştırmak istemez.
Andrew Steitz


Teşekkürler, ihtiyacım olan şey buydu :-) Try olmadan da çalışırsa gerçekten harika olurdu {} Yani: async () => {indicWorkInProgress () await pipelineStep1 () await pipelineStep2 () ... nihayet {stopIndicator ( )}} Tüm işlevin kastedildiği açıktır ;-) Bu deneme blokları orada çok çirkin ...
Lenny

35

ES2019'dan başlayarak bir hata değişkeni olmadan boş bir catch bloğuna sahip olmak mümkündür . Buna isteğe bağlı yakalama bağlama adı verilir ve Haziran 2018'de yayınlanan V8 v6.6'da uygulanmıştır . Bu özellik, Node 10 , Chrome 66 , Firefox 58 , Opera 53 ve Safari 11.1'den beri mevcuttur .

Sözdizimi aşağıda gösterilmiştir:

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

Hala bir catchbloğa ihtiyacınız var , ancak boş olabilir ve herhangi bir değişkeni geçirmenize gerek yoktur. Bir catch bloğu istemiyorsanız try/ kullanabilirsiniz finally, ancak boş bir catch bloğu gibi hataları yutmayacağını unutmayın.

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


2
bu cevap en güncel cevaptır! yürütme sırası açısından, 1. trybloğu dener . 2. Hatayı yakalar. 3. finallyBloğu yürütür . 4. Hatayı atar. Bu doğru mu?
helsont

Teşekkürler @helsont. İkinci kod örneğindeki yürütme sırasına gelince, hatanın yakalanıp yeniden atıldığını ya da sadece (muhtemelen) basitçe fırlatılıp atılmadığını (olmadığı için) anlayabileceğinden emin değilim catch. Tüm kodu başka bir try/ ile çevreleyin vecatchThis WILL get logged hatayı yakalayabilirsiniz .
Dan Dascalescu

Artık çok temiz görünüyor. Paylaşım için teşekkürler!
LeOn - Han Li

10

Hayır, catch(veya finally) try'nin arkadaşıdır ve dene / yakala'nın bir parçası olarak her zaman oradadır .

Bununla birlikte, sizin örneğinizde olduğu gibi, bunların boş olması tamamen geçerlidir.

Örnek kodunuzdaki yorumlarda ( eğer func1 hata verirse, func2'yi deneyin ), gerçekten yapmak istediğiniz şey bir catchönceki bloğun içindeki sonraki işlevi çağırmak gibi görünüyor .


1
Haklısın Bununla birlikte, kod benzeri try {...}; try {...}mümkünse, kodun anlamı daha net olabilir (ilkini deneyin, aksi takdirde ikinciyi deneyin).
pimvdb

Düzenlemeniz hakkında: JSFiddle örneğinde, ikinci işlev bir şey döndürür, bu durumda üçüncü işlev gerçekten bu durumda değerlendirilir mi? Bir returnifadenin ondan sonra gelen her şeyi durdurduğunu sanıyordum .
pimvdb

@pimvdb Üzgünüm, keman kontrol etmedim. returnişlevin erken dönmesine neden olur. Cevabımı güncelleyeceğim.
alex

1
Bu cevap, sen dayanarak yanlış olması olabilir edilir try {}; finally {}olarak gösterilen stackoverflow.com/a/5764505/68210
Daniel X Moore'a

1
@DanielXMoore Elbette öyle, ama finally{}temelde aynı ruhta catch{}. Cevabı güncelleyeceğim.
alex

6

Yakalama olmadan dene-nihayet önermem, çünkü hem try bloğu hem de nihayet blok atma hataları olursa, final cümlesinde atılan hata köpürür ve try bloğunun hatası kendi testimde göz ardı edilir:

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

Sonuç:

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

1

Bunlara sahip olduğunu bildiğim her dilde (JavaScript, Java, C #, C ++) birlikte geliyorlar. Yapma.


1
Benimki beş yıl sonra buradaki diğer cevaplarla aynı şeyi söyleyince reddedilmişti. Görünüşe göre benimki olumsuz oy alan tek kişi. Moderatörler, lütfen not alın.
duffymo

Tcl çok kullanışlı bir tek kelimelik yapıya sahipcatch {my code}
MKaama


Neden? Denemedikçe / nihayetinde işe yaramaz.
duffymo

1

Sunulan soruna farklı bir açıdan bakmaya karar verdim.

Kısmen başka bir yorumcu tarafından listelenen işlenmemiş hata nesnesini ele alırken, istenen kod modeline yakından izin vermenin bir yolunu belirleyebildim.

kod görülebilir @ http://jsfiddle.net/Abyssoft/RC7Nw/4/

try: catch, zarif bir düşüşe izin veren bir for döngüsü içine yerleştirilir. ihtiyaç duyulan tüm işlevler arasında yineleme yapabilmek. açık hata işleme gerektiğinde, ek işlev dizisi kullanılır. hata durumunda hata ve işlevsel dizi ile hata işleyicileri öğesi bir işlev değildir, hata konsola dökülür.

Stackoverflow gereksinimlerine göre, burada kod satır içi [JSLint uyumlu hale getirmek için düzenlenmiştir (onaylamak için öndeki boşlukları kaldırın), okunabilirliği iyileştirin]

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], [], []));


1

Bir hata oluştuğunda sadece 2 ve 3 numaralı fonksiyonların ateşlenmesini istiyorsanız, neden onları catch bloğuna koymuyorsunuz?

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

0

Yardımcı işlevi aşağıdaki gibi kullanmanız gerektiğine inanıyorum:

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

ve şu şekilde kullanın:

tryIt(function1, /* args if any */);
tryIt(function2, /* args if any */);


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.