спробувати {} без JavaScript {} можливо в JavaScript?


114

У мене є ряд функцій, які або повертають щось, або видаляють помилку. У головній функції я викликаю кожну з них і хотів би повернути значення, повернене кожною функцією, або перейти до другої функції, якщо перша функція видасть помилку.

Тому в основному те, що я зараз маю:

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
}

Але насправді я хотів би лише tryповернути його (тобто, якщо він не видасть помилку). Мені не потрібен catchблок. Однак такий код try {}не вдається, оскільки в ньому відсутній (невикористаний) catch {}блок.

Я ставлю приклад на jsFiddle .

Отже, чи можна catchвидалити ці блоки, досягаючи того ж ефекту?

Відповіді:


4

Ні. Ви повинні їх тримати.

Це насправді має сенс, оскільки помилки взагалі не слід ігнорувати.


16
У цьому випадку ці функції не повинні видаляти помилки, а повертатися, наприклад, nullі ви робите щось на кшталтreturn func1() || func2() || func3();
ThiefMaster

52
Ця відповідь фактично невірна, ви можете мати, try {}; finally {}як показано в stackoverflow.com/a/5764505/68210
Даніель Х Мур

4
@DanielXMoore, без цього catch (e) {}винятку, що викинеться, func1()заважатиме func2()судити.
бінкі

65
Іноді має сенс мати порожній вилов, тому я не згоден з вашим аргументом.
Петро Пеллер

8
Ця відповідь є фактично неправильною та оманливою. "Це насправді має сенс" ви говорите, але ви помиляєтесь, це має сенс лише в деяких випадках, а не в інших. Це чудовий приклад того, що страшна відповідь приймається незрозуміло. Існує багато випадків, коли asyncіноді є сенс не мати блоку лову, як, наприклад, у функції. Змушувати мову JavaScript створювати порожні catchблоки явно безглуздо.
YungGun

236

Спроба без улову пункту відправляє повідомлення про помилку на наступний більш високий улов , або у вікно, якщо немає ніякого підступу визначається в межах цієї спроби.

Якщо у вас немає улову , випробувальний вираз вимагає остаточного застереження.

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

Тож найкращим способом було б написати щось на кшталт try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { //always run}}}?
користувач2284570

1
Вище коментар не відповідає точно ОП, оскільки він не хоче запускати функцію 2, якщо функція 1 успішна.
Ендрю Штайц


Дякую, що мені це було потрібно :-) Було б справді приголомшливо, якщо воно також працює без спроб {} Я маю на увазі: async () => {indicWorkInProgress () очікуємо pipelineStep1 () очікуємо pipelineStep2 () ... нарешті {stopIndicator ( )}} Було б зрозуміло, що вся функція має на увазі ;-) Ці
Ленні

35

Можна мати порожній блок лову, без змінної помилки, починаючи з ES2019 . Це називається необов'язковим прив'язкою улову та було реалізовано у V8 v6.6, випущеному у червні 2018 року . Ця функція доступна з Node 10 , Chrome 66 , Firefox 58 , Opera 53 та Safari 11.1 .

Синтаксис показаний нижче:

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

Вам все одно потрібен catchблок, але він може бути порожнім і вам не потрібно передавати жодну змінну. Якщо ви взагалі не хочете блокування лову, ви можете скористатися try/ finally, але зауважте, що він не проковтне помилок, як це робить порожній.

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


2
ця відповідь є найсучаснішою! з точки зору наказу про виконання, 1. він намагається tryблокувати. 2. Вловлює помилку. 3. Виконує finallyблок. 4. Викидає помилку. Це правильно?
helsont

Дякую @helsont. Щодо наказу про виконання у другому зразку коду, я не впевнений, що можна сказати, чи помилка підхоплена і повторно викинута, або просто (ймовірно) просто кинута і не попалася в першу чергу (оскільки її немає catch). Оточіть весь код іншим try/,catch і ви зможете зрозумітиThis WILL get logged помилку.
Дан Даскалеску

Зараз виглядає дуже чисто. Дякую, що поділились!
LeOn - Хан Лі

10

Ніп, catch(або finally) є tryдругом і завжди є частиною спроби / лову .

Однак цілком справедливо, щоб вони були порожніми, як у вашому прикладі.

У коментарях до вашого прикладу коду ( Якщо func1 видає помилку, спробуйте func2 ), здається, що ви дійсно хочете зробити це викликати наступну функцію всередині catchблоку попереднього.


1
Ти прав. Однак якщо подібний код try {...}; try {...}буде можливим, значення коду може бути зрозумілішим (спробуйте перший, інакше спробуйте другий).
pimvdb

Про вашу редагування: У прикладі JSFiddle друга функція повертає щось, тож чи дійсно в цьому випадку оцінюється третя функція? Я подумав, що returnзаява зупиняє будь-що, що йде після неї.
pimvdb

@pimvdb Вибачте, я не перевірив скрипку. returnпризведе до повернення функції передчасно. Я оновлю свою відповідь.
alex

1
Ця відповідь фактично невірна, ви можете мати, try {}; finally {}як показано в stackoverflow.com/a/5764505/68210
Даніель Х Мур

1
@DanielXMoore Звичайно, це, але finally{}в основному в тому ж дусі, що і catch{}. Я оновлю відповідь.
alex

6

Я б не рекомендував спробувати, нарешті, без уловки, тому що якщо помилка блоку спробу і остаточний блок викинуть помилки, помилка, викинута в остаточному пункті, роздувається, і помилка блоку спробу ігнорується в моєму власному тесті:

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

Результат:

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

1

Вони йдуть разом усіма мовами, які я знаю, що їх є (JavaScript, Java, C #, C ++). Не робіть цього.


1
Як не дивно, що міна була знята через п’ять років, коли вона говорить те саме, що й інші відповіді. Моя, здається, є єдиною, яка була заборонена. Модератори, будь ласка, зверніть увагу.
duffymo

Tcl має дуже зручну односкладну конструкціюcatch {my code}
MKaama


Чому? Відчуває себе марним, якщо тільки не спробувати / нарешті.
duffymo

1

Я вирішив переглянути проблему, представлену з іншого кута.

Мені вдалося визначити спосіб уважно дозволити запитуваний код коду, частково звертаючись до необробленого об'єкта помилки, перерахованого іншим коментатором.

код можна побачити @ http://jsfiddle.net/Abyssoft/RC7Nw/4/

спробуйте: улов розміщується в циклі for, що дозволяє витончено провалитися. маючи можливість повторити всі необхідні функції. коли потрібна явна обробка помилок, використовується додатковий масив функцій. в парному рівні помилок і функціональний масив з елементом обробці помилок не є функцією, помилка скидається на консоль.

Відповідно до вимог stackoverflow тут є вбудований код [відредагований, щоб зробити JSLint сумісним (видалити провідні пробіли для підтвердження), покращити читабельність]

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

Якщо ви хочете, щоб функції 2 і 3 спрацьовували лише у випадку помилки, чому ви не ставите їх у блок лову?

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

0

Я вважаю, що вам потрібно використовувати функцію помічника, наприклад:

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

і використовувати його так:

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

-2

пробувати і ловити - це як 2 сторони однієї монети. тому неможливо без спроб.


5
Ця відповідь фактично неправильна, ви можете мати, try {}; finally {}як показано в stackoverflow.com/a/5764505/68210
Даніель Х Мур,


-2

З ES2019 ви можете легко користуватися try {}без catch {}:

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

Для отримання додаткової інформації зверніться до пропозиції Майкла Фікара


1
Ні, catchвсе-таки потрібно, це просто обов'язкове оформлення, яке не потрібно ...
chipit24
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.