Что я в итоге сделал
Я добавил функцию секвенирования в свою мини-библиотеку асинхронных вспомогательных функций. По сути, он выполняет последовательность вызовов «then», за исключением того, что добавляет дополнительные промежуточные шаги для переброса любых исключений, которые в конечном итоге перехватываются отложенными. Он также принимает необязательный обработчик ошибок для перехвата исключений.
Когда я это называю, это выглядит так:
go([
function(){
return 17;
},
function(x){
//return some stuff
},
function(){
var obj = a_function_that_returns_null_on_IE();
var x = obj.some_property; //BOOM!
}
], function(){
//an optional error handler
});
Другая причина, по которой я так поступил, заключается в том, что у меня много кода, который должен работать одновременно с синхронизирующим или асинхронным кодом (используя Deferred.when для создания цепочки). Использование моей пользовательской функции позволяет мне использовать единый унифицированный синтаксис, и ошибки, которые не фиксируются в асинхронном случае, соответствуют случаю синхронизации, в котором не задействованы отложенные элементы. Я также думаю, что все в порядке, чтобы не фиксировать ошибку, поскольку в отличие от общего случая, когда я использую «go», я априори знаю, какой код будет вызываться, поэтому нет необходимости перехватывать исключения, если кому-то нужно перехватить их в будущем.
Кроме того, использование нестандартного решения дало мне свободу применять некоторые личные настройки дизайна:)
В дополнение к этому я в конечном итоге сократил количество исключений, которые я генерирую сам по всей базе кода. Управление исключениями в асинхронном коде более раздражает, чем обычно, и иногда проще просто вернуться к обработке ошибок, возвращая ноль или код ошибки.
Кроме того, мы убедились, что любые исключения, которые мы создаем сами, являются экземплярами встроенного класса Error, целого ряда других объектов. Причина в том, что встроенный класс Error записывает номер строки и трассировку стека, где он был сгенерирован, кросс-браузерным способом.