Когда генерируются асинхронные методы и как вы их ловите?

Из документа узла:

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

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

В частности. Они относятся к такой функции:

try
{

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

}

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

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

2 ответа

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

Но в 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
}

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

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

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

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

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

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

  • Обещания:

function foo(){ return Promise.resolve('bar') }

foo().then(value => value =========> 'error')
.catch(err => {
 console.error(err);
 return "fixedValue";
});

  • И Синтаксис / шаблон обратного вызова узлов:

function foo(value, callback){
setTimeout(function(){
 if(Math.random() < .5){
  callback("I don't like to", undefined);
 }else{
  callback(null, value * 2);
 }
}, 500);
}

foo(21, function(err, data){
if(err){
 //no try..catch at all
 console.error(err);
}else{
 //do whatever with data
}
})

Это наиболее распространенные асинхронные ошибки, с которыми вы столкнетесь; Ну, первый из них - просто ошибка в асинхронном режиме.

Другие вопросы по тегам