.then () в Entries.tsx не запустился бы, если бы произошла ошибка, поскольку в этой ситуации уже есть перехватчик?
Это не совсем правильно.
catch
блок в методе getTasks
в backendService.ts
файле возвращает undefined
и , когда блок catch
возвращает значение вместо того, чтобы генерировать перехваченную ошибку, вместо вызова catch
блок вызывающего кода, then
блок вызывается .
Это происходит потому, что Promise
, возвращаемый методом getTasks
в файле backendService.ts
, зависит от следующего:
Если Promise
, возвращаемый axios.get(...)
, соответствует тому, что вы делаете в блоке then(...)
Если Promise
вернул by axios.get(...)
отклоняется, тогда то, что вы делаете в блоке catch(...)
В вашем случае, если Promise
, возвращенный axios.get(...)
, выполняется, тогда блок then(...)
будет execute, и поскольку он просто возвращает tasks
, Promise
, возвращенный методом getTasks
в backendService.ts
файле, выполняется, что приводит к вызову then(...)
блок в вызывающем коде, то есть в файле Entries.tsx
.
Если Promise
, возвращенный axios.get(...)
, отклоняется, блок catch(...)
будет выполнен. Поскольку блок catch(...)
в методе getTasks
просто регистрирует ошибку, Promise
, возвращаемый методом getTasks
, будет выполнен со значением undefined
, что приведет к вызову Блок then(...)
в вызывающем коде , т.е. в файле Entries.tsx
.
Чтобы понять это, см. Следующий пример.
function getData() {
// incorrect url which will lead to response.ok being false
const url = 'https://jsonplaceholder.typicode.com/todo/1';
return fetch(url)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error();
}
})
.catch(error => console.log('catch block in getData function'));
}
getData()
.then(data => console.log('then block ran'))
.catch(error => console.log('error block ran'));
В приведенном выше фрагменте кода, поскольку URL-адрес API неверен, response.ok
в блоке then
является ложным, поэтому ошибка возникает из блока then
который перехватывается блоком catch
в той же функции. Поскольку этот блок catch
просто регистрирует сообщение и возвращает undefined
, Promise
, возвращаемый функцией getData
, выполняет со значением undefined
. Таким образом, вместо блока catch
блок then
выполняется в коде, который вызывает функцию getData
.
Если вы этого не знали, вы можете быть удивлены, увидев такое поведение, но вот как Promises
работает с catch
блоками. Причина такого поведения в том, что если у вас есть цепочка обещаний, содержащая более одного блока catch
, как показано ниже:
fetch(...)
.then(...)
.catch(...)
.then(...)
.then(...)
.catch(...);
, тогда, если первый блок catch
улавливает ошибку, которая выдается от любой из функций, связанных перед ним, то этот блок catch
может выполнять одно из следующих двух действий:
- выдавать ошибку, которая затем приведет к вызову последнего блока
catch
- обрабатывает ошибку и возвращает некоторое значение
, если первый блок catch
возвращается нормально, обещание, возвращаемое блоком catch
, выполняется с этим возвращаемым значением catch
block, и это значение затем становится входом функции обратного вызова следующего блока then
в цепочке обещаний. Таким образом, цепочка обещаний продолжается, а не останавливается, как только выполняется первый catch
блок.
Возвращаясь к вашему коду, когда блок catch
выполняется в методе getTasks
в файле backendService.ts
, он регистрирует сообщение и возвращает undefined
, что затем приводит к вызову блока then
в Entries.tsx
вместо блока catch
, поэтому вы получаете жалобу от машинописного текста на ваш код.
Решение
Вы можете использовать один из следующие варианты решения этой проблемы:
Вывести ошибку, обнаруженную в блоке catch(...)
метода getTasks
в файле backendService.ts
, чтобы Promise
возвращалось методом getTasks
отклоняется вместо выполнения со значением undefined
.
Удалите блок catch
в функции getTasks
в файле backendService.ts
и добавьте блок catch
в код, вызывающий метод getTasks
.
На мой взгляд, нет необходимости в блоке catch
в файле backendService.ts
, потому что, если Promise
, возвращенный axios.get(...)
, отклоняется, Promise
, возвращенный методом getTasks
, также будет отклонен, если в методе getTasks
нет блока catch
. Поэтому просто удалите блок catch(...)
из метода getTasks
и добавьте блок catch(...)
, в котором вы вызываете этот метод getTasks
.