我有一个基于promise的API服务,它从我的后端请求数据。它也有自己的错误捕获,所以我不必到处写它。当它这样写的时候:
BackendService.ts
...
getTasks() {
return axios.get('/api/tasks')
.then((response) => {
const {
tasks
}: {
tasks: tasksType
} = response.data;
return tasks;
})
.catch((error) => console.log(error));
}
...
请点击.tsx
...
const getTasks = () => {
backendService.getTasks()
.then((tasks: tasksType) => {
const filteredTasksData = filterAPIDataForState(tasks);
addTasks({
tasks: filteredTasksData
});
})
}
...
我得到以下错误:
TS2345: Argument of type '(tasks: tasksType) => void'
is not assignable to parameter of type '(value: void | tasksType) => void | PromiseLike<void>'.Types of parameters 'tasks'
and 'value'
are incompatible.Type 'void | tasksType'
is not assignable to type 'tasksType'.Type 'void'
is not assignable to type 'TaskInterface[]'.
我猜这是因为catch,它可以使Promise不返回任何东西(因为console.log)。如果我给予getTasks
从Entries.tsx
它自己的catch处理程序,并从BackendService.ts getTasks
中删除它,它就可以工作。
如果出现错误,Typescript不应该知道Entries.tsx
中的.then()
不会运行,因为已经有一个catch处理这种情况了吗?
2条答案
按热度按时间wj8zmpe11#
如果出现错误,则.then()在.tsx中不会运行,因为已经有一个catch处理这种情况?
这并不完全正确。
backendService.ts
文件中getTasks
方法中的catch
块返回undefined
和**,而catch
块返回值**,而不是:在调用代码中,不是调用
catch
块,而是调用**then
块**。这是因为
backendService.ts
文件中的getTasks
方法返回的Promise
依赖于以下内容:axios.get(...)
返回的Promise
满足,那么您在then(...)
块中执行的操作axios.get(...)
返回的Promise
被拒绝,那么在catch(...)
块中执行的操作在您的例子中,如果
axios.get(...)
返回的Promise
满足,那么then(...)
块将执行,因为它只返回tasks
,所以backendService.ts
文件中的getTasks
方法返回的Promise
满足,导致调用代码中的then(...)
块,即在Entries.tsx
文件中。如果
axios.get(...)
返回的Promise
被拒绝,则catch(...)
块将执行。由于getTasks
方法中的catch(...)
块只是记录错误,因此getTasks
方法返回的Promise
将满足undefined
的值,这将导致调用代码中调用then(...)
块,即在Entries.tsx
文件中。请看下面的例子来理解这一点。
在上面的代码片段中,由于API URL不正确,
then
块中的response.ok
为false,因此从同一函数中的catch
块捕获的then
块中抛出错误。由于这个catch
块只是记录一条消息并隐式返回undefined
,因此getData
函数返回的Promise
满足undefined
的值。因此,在调用getData
函数的代码中执行的不是catch
块,而是then
块。如果你不知道这一点,那么你可能会惊讶地看到这种行为,但这就是promise如何与
catch
块一起工作的。这种行为的原因是,如果你有一个promise链,它有一个以上的catch
块,如下所示:那么如果第一个
catch
块捕获了一个从它之前链接的任何方法抛出的错误,那么这个catch
块可以做以下两件事之一:catch
块如果第一个
catch
块正常返回,则catch
块返回的promise将满足catch
块的返回值,然后该值成为promise链中下一个then
块的回调函数的输入。因此,promise链继续运行,而不是在第一个catch
块执行后立即停止。回到你的代码,当
catch
块在backendService.ts
文件中的getTasks
方法中执行时,它记录消息并返回undefined
,然后导致调用Entries.tsx
文件中的then
块,而不是catch
块,这就是为什么你会收到typescript对你代码的抱怨。解决方案
您可以使用以下选项之一来解决此问题:
backendService.ts
文件中getTasks
方法的catch(...)
块中捕获的错误,以便拒绝getTasks
方法返回的Promise
,而不是使用undefined
的值来实现。backendService.ts
文件中getTasks
函数中的catch
块,并在调用getTasks
方法的代码中添加catch
块。在我看来,在
backendService.ts
文件中不需要catch
块,因为如果axios.get(...)
返回的Promise
被拒绝,那么如果getTasks
方法中没有catch
块,getTasks
方法返回的Promise
也会被拒绝。因此,只需从getTasks
方法中删除catch(...)
块,并在调用此getTasks
方法的位置添加catch(...)
块。bsxbgnwa2#
有很多选择来处理这一点
1.在BackendService.getTasks()中,只需删除.catch()并在.getTasks()中处理.catch()即可。
1.在BackendService.getTasks()中添加另一个then并返回空任务,例如.then(it => it|| [])
Axios不会在响应错误时崩溃,因此您必须正确检查响应并处理它,因为它不应该只是盲目地破坏响应对象