Vin*_*ent 6 javascript promise typescript axios
我有一个基于承诺的 API 服务,它从我的后端请求数据。它还带有自己的错误捕获,因此我不必到处编写它。当它写成这样时:
后端服务.ts
...
getTasks() {
return axios.get('/api/tasks')
.then((response) => {
const {
tasks
}: {
tasks: tasksType
} = response.data;
return tasks;
})
.catch((error) => console.log(error));
}
...
Run Code Online (Sandbox Code Playgroud)
条目.tsx
...
const getTasks = () => {
backendService.getTasks()
.then((tasks: tasksType) => {
const filteredTasksData = filterAPIDataForState(tasks);
addTasks({
tasks: filteredTasksData
});
})
}
...
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
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[]'.
Run Code Online (Sandbox Code Playgroud)
我想这是因为捕获,这可能会使 Promise 不返回任何内容(因为 console.log)。如果我给出getTasksfromEntries.tsx它自己的 catch 处理程序并将其从 BackendService.ts 中删除getTasks,它就会起作用。
难道 Typescript 不应该能够告诉我们,如果出现错误,则.then()in不会运行,因为已经有一个 catch 来处理这种情况?Entries.tsx
如果出现错误,Entries.tsx 中的 .then() 将不会运行,因为已经有一个 catch 来处理这种情况?
这并不完全正确。
catchgetTasks文件中的方法中的块backendService.ts正在返回undefined,并且当catch块返回一个值而不是:
不是catch在调用代码中调用 block,而是then调用 block。
发生这种情况是因为文件中的方法Promise返回的值取决于以下内容:getTasksbackendService.ts
如果Promise返回的内容满足,那么你在块axios.get(...)中做什么then(...)
如果Promise返回被axios.get(...)拒绝那么你在catch(...)块中做什么
在您的情况下,如果Promise由axios.get(...)fulfils 返回,则then(...)块将执行,并且因为它只返回由文件中的方法返回的 fulfils tasks,导致在调用代码中调用该块,即在文件中。PromisegetTasksbackendService.tsthen(...)Entries.tsx
如果Promise返回的axios.get(...)被拒绝,catch(...)则块将执行。由于方法catch(...)中的块getTasks只是记录错误,因此方法Promise返回的值将导致在调用代码(即文件中)中调用块。getTasksundefinedthen(...)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'));Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,由于 API URL 不正确,response.ok块中的then值为 false,因此从块中抛出错误,该错误被同一函数中的块then捕获。catch由于此catch块只是记录一条消息并隐式返回undefined,Promise因此函数getData返回的值为undefined。因此catch,then块不是在块中执行,而是在调用该getData函数的代码中执行。
如果您不知道这一点,那么您可能会惊讶地看到这种行为,但这就是承诺与catch块的工作方式。出现这种行为的原因是,如果您有一个包含多个catch块的 Promise 链,如下所示:
fetch(...)
.then(...)
.catch(...)
.then(...)
.then(...)
.catch(...);
Run Code Online (Sandbox Code Playgroud)
那么如果第一个catch块捕获了从它之前链接的任何方法引发的错误,则该catch块可以执行以下两件事之一:
catch承诺链中的下一个块如果第一个catch块正常返回,则块返回的 Promisecatch将满足该块的返回值,然后该值将成为Promise 链中catch下一个块的回调函数的输入。then因此,承诺链会继续,而不是在第一个catch块执行后立即停止。
回到你的代码,当块在文件中的方法catch中执行时,它会记录消息并返回,然后导致调用文件中的块,而不是块,这就是为什么你会收到打字稿的投诉你的代码。getTasksbackendService.tsundefinedthenEntries.tsxcatch
解决方案
您可以使用以下选项之一来解决此问题:
将方法catch(...)块中捕获的错误抛出到文件中,以便方法返回被拒绝,而不是用 的值来实现。getTasksbackendService.tsPromisegetTasksundefined
删除文件中函数catch中的块,并在调用方法的代码中添加该块。getTasksbackendService.tscatchgetTasks
catch在我看来,文件中不需要块backendService.ts,因为如果方法Promise返回axios.get(...)被拒绝,那么如果方法中没有块,则方法Promise返回也将被拒绝。因此,只需从方法中删除该块,然后在调用该方法的位置添加该块即可。getTaskscatchgetTaskscatch(...)getTaskscatch(...)getTasks
有很多选项可以处理这个问题
当响应错误时,axios不会崩溃,所以你必须正确检查响应并处理它,因为它不应该只是盲目地破坏响应对象
| 归档时间: |
|
| 查看次数: |
5835 次 |
| 最近记录: |