Существует много руководств о том, как использовать "then" и "catch" при программировании с помощью JavaScript Promise. Тем не менее, все эти учебные пособия, похоже, пропустят важный момент: возвращение из блока then/catch, чтобы разбить цепочку Promise. Начнем с некоторого синхронного кода, чтобы проиллюстрировать эту проблему:
try {
someFunction();
} catch (err) {
if (!(err instanceof MyCustomError))
return -1;
}
someOtherFunction();
В сущности, я тестирую пойманную ошибку, и если это не ошибка, которую я ожидаю, я вернусь к вызывающему, иначе программа продолжится. Однако эта логика не будет работать с Promise:
Promise.resolve(someFunction).then(function() {
console.log('someFunction should throw error');
return -2;
}).catch(function(err) {
if (err instanceof MyCustomError) {
return -1;
}
}).then(someOtherFunction);
Эта логика используется для некоторых моих модульных тестов, где я хочу, чтобы функция терпит неудачу определенным образом. Даже если я изменю catch на тот блок, я все еще не могу сломать цепочку цепочек Promises, потому что все, что возвращается из блока then/catch, станет Promise, распространяющимся по цепочке.
Интересно, может ли Promise достичь этой логики; если нет, то почему? Мне очень странно, что цепь обещаний никогда не может быть нарушена. Спасибо!
Изменить на 08/16/2015: Согласно ответам, данным до сих пор, отклоненное обещание, возвращенное тогдашним блоком, будет распространяться через цепочку обещаний и пропускать все последующие блоки до тех пор, пока оно не будет поймано (обработано). Это поведение хорошо понято, потому что оно просто имитирует следующий синхронный код (подход 1):
try {
Function1();
Function2();
Function3();
Function4();
} catch (err) {
// Assuming this err is thrown in Function1; Function2, Function3 and Function4 will not be executed
console.log(err);
}
Однако то, что я спрашивал, это следующий сценарий синхронного кода (подход 2):
try {
Function1();
} catch(err) {
console.log(err); // Function1 error
return -1; // return immediately
}
try {
Function2();
} catch(err) {
console.log(err);
}
try {
Function3();
} catch(err) {
console.log(err);
}
try {
Function4();
} catch(err) {
console.log(err);
}
Я хотел бы иметь дело с ошибками, возникающими в разных функциях по-разному. Возможно, я поймаю все ошибки в одном блоке catch, как показано в подходе 1. Но таким образом я должен сделать большой оператор switch внутри блока catch, чтобы различать различные ошибки; кроме того, если ошибки, вызванные разными функциями, не имеют общего переключаемого атрибута, я вообще не смогу использовать оператор switch; в такой ситуации я должен использовать отдельный блок try/catch для каждого вызова функции. Подход 2 иногда является единственным вариантом. Разве Promise не поддерживает этот подход с помощью инструкции then/catch?