2016-02-25 1 views
2

Я немного запутался в понимании ошибки обработки ошибок. Предположим, что у меня есть следующие функции (только для демонстрации):Обработка ошибок в Q-обещании

function first() { 
    console.log('first'); 
    var done = Q.defer(); 
    done.resolve('first'); 
    return done.promise; 
} 

function second() { 
    console.log('second'); 
    var done = Q.defer(); 
    done.resolve('second'); 
    return done.promise; 
} 

function third() { 
    console.log('third'); 
    var done = Q.defer(); 
    done.resolve('third'); 
    return done.promise; 
} 

function fourth() { 
    console.log('fourth'); 
    var done = Q.defer(); 
    done.resolve('fourth'); 
    return done.promise; 
} 

function doWork() { 
    return first().then(function() { 
     return second(); 
    }).then(function() { 
     return third() 
    }).then(function() { 
     return fourth(); 
    }); 
} 

doWork().catch(function(err) { 
    console.log(err); 
}); 

Все прошло хорошо.

Теперь, если в второго, третьего или четвертой функции, у меня есть некоторые ошибки (брошенные в асинхронном вызове, например), я мог бы поймать его изящно.

Например, если в второго, третьего или четвертой функции, я добавляю: поймана

throw new Error('async error'); 

ошибка. Отлично!

Но то, что меня смущает, заключается в том, что если ошибка возникает в первой функции, ошибка не поймана и это прерывает мое выполнение.

Пожалуйста, скажите мне, почему или что я делаю неправильно?

Большое спасибо!

ответ

4

Только исключения в then обратные вызовы пойманы обеими реализациями. Если вы throw в first, исключение будет пузыриться и будет поймано только приложением try-catch.

Именно поэтому асинхронные функции (обещание-возврат) should never throw. Вместо этого отклоните обещание, которое вы возвращаете (done.reject(…) или return Q.reject(…)). Если вы не доверяете своей функции, вы можете использовать Promise.resolve().then(first).…, чтобы начать свою цепочку.

+2

Кроме того, вы можете начать цепочку с 'q.fcall (первая) .Затем (второй) ...' – the4lt

+0

@ the4lt: Да, конечно, я забыл, что это Q-конкретный вопрос. 'resolve(). then (...)' по сути то же самое, но более портативный. – Bergi

+0

Спасибо, теперь яснее, как это работает. – passkey1510

1

Оберните логику, которая может сломаться в блоке try, и reject обещание с ошибкой в ​​блоке catch.

var def = q.defer(); 
try { 
    // sync or async logic that can break 
} 
catch (ex) { 
    q.reject(ex); 
} 
return def;