Когда методы асинхронного броска и как вы их поймаете?

Из node doc:

Несколько типичных асинхронных методов в API Node.js может по-прежнему использовать механизм броска для создания исключений, которые необходимо обработать используя try/catch. Нет исчерпывающего списка таких методов; обратитесь к документации каждого метода для определения необходим соответствующий механизм обработки ошибок.

Может ли кто-нибудь привести пример такой функции, которая асинхронна и по-прежнему бросает? Как и когда вы получаете исключение?

Более конкретно. Они относятся к такой функции:

try
{

   obj.someAsync("param", function(data){
                    console.log(data);
                 });
}catch(e)
{

}

Теперь, как правило, я знаю выше, не имеет смысла, потому что, когда выполняется обратный вызов, блок try мог уже выйти.

  • Но какой пример содержит отрывок из документации? Если метод async выбрасывает, как говорится, где, когда и как я должен его обрабатывать? (или, может быть, если вы покажете такую ​​функцию, можете ли вы показать, где в ее документе говорится, как обращаться с ней, как указано в цитате?)

Ответ 1

Асинхронные методы, подобные одному из вашего примера, обычно вызывают ошибки программиста, такие как плохие параметры, и они вызывают обратный вызов с ошибкой для операционных ошибок.

Но есть также асинхронные функции в ES2017 (объявленные с помощью async function) и эти ошибки сигнала, отклоняя обещание, которое они возвращают, - которые превращаются в исключение, когда вы используете их с ключевым словом await.

Примеры:

function x(arg, cb) {
    if (!arg) throw new Error('Programmer error: bad arguments');
    setTimeout(() => {
        cb(new Error('Operational error: something bad happened'));
    }, 2000);
}

Теперь, когда вы используете его, вы обычно не хотите обрабатывать ошибки программиста - вы хотите их исправить. Поэтому вы не делаете этого:

try {
    x();
} catch (err) {
    // Why should I handle the case of bad invocation
    // instead of fixing it?
}

И операционные ошибки, которые вы обрабатываете следующим образом:

x(function (err) {
    if (err) {
        // handle error
    } else {
        // success
    }
});

Теперь, если у вас есть функция, которая не выполняет обратный вызов, но возвращает обещание:

function y() {
    return new Promise((res, rej) => setTimeout(() => rej('error'), 2000));
}

Затем вы обрабатываете ошибку следующим образом:

y().catch(error => {
    // handle error
});

или, используя await:

try {
    await y();
} catch (err) {
    // handle error
}

Для получения дополнительной информации о различии между операционными ошибками и ошибками программиста см.:

Для получения дополнительной информации о promises и async/await см. ссылки в этом ответе.

Ответ 2

afaik существует три способа, которые функция async могла бы "бросить"; и как поймать каждый из них:

  • как любая другая функция (иначе кто-то испортил): я не поймал бы эти случаи, потому что они не должны быть в моем коде, и ловить такие ошибки затрудняет их поиск и исправление.

function foo(){
//someone messed up, better fixing than catching this
return new Prooooooooooomise((resolve) => 42);
}

try {
foo();
}catch(err){
console.error(err);
}