[英]Handle Promise Catches in Typescript
我有一個基於 promise 的 API 服務,它從我的后端請求數據。 它還帶有自己的錯誤捕獲,所以我不必到處寫它。 當它這樣寫時:
后端服務.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[]'.
我想這是因為捕獲,這可能會使 Promise 什么都不返回(因為 console.log)。 如果我從Entries.tsx
給getTasks
它自己的 catch 處理程序並將其從 BackendService.ts getTasks
中刪除,它就可以工作。
如果出現錯誤,Typescript 是否應該能夠判斷Entries.tsx
中的 .then .then()
不會運行,因為已經有處理這種情況的捕獲?
如果出現錯誤,Entries.tsx 中的 the.then() 將不會運行,因為已經有一個 catch 處理這種情況?
這並不完全正確。
backendService.ts
文件中getTasks
方法中的catch
塊返回undefined
,當catch
塊返回一個值而不是拋出捕獲的錯誤時,而不是調用調用代碼的catch
塊, then
調用塊。
發生這種情況是因為Promise
文件中getTasks
方法返回的backendService.ts
取決於以下內容:
如果Promise
axios.get(...)
返回的 Promise 滿足,那么您在then(...)
塊中執行的操作
如果Promise
axios.get(...)
返回的 Promise 被拒絕,那么您在catch(...)
塊中執行的操作
在您的情況下,如果Promise
axios.get(...)
滿足,則then(...)
塊將執行,並且由於它只返回tasks
, Promise
中的getTasks
方法backendService.ts
文件。在調用代碼中調用then(...)
塊,即在Entries.tsx
文件中。
如果Promise
axios.get(...)
返回的 Promise 被拒絕,則將執行catch(...)
塊。 由於getTasks
方法中的catch(...)
塊只是記錄錯誤, 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'));
在上面的代碼片段中,由於 API URL 不正確, then
塊中的response.ok
為 false,因此從then
塊中拋出錯誤,該塊被同一 ZC1C425268E68385D1AB5074C 中的catch
塊捕獲。 由於這個catch
塊只是記錄一條消息並返回undefined
,因此getData
Promise
返回的 Promise 滿足undefined
的值。 因此,代替catch
塊, then
塊在調用getData
function 的代碼中執行。
如果您不知道這一點,那么您可能會驚訝地看到這種行為,但這就是Promises
與catch
塊一起工作的方式。 這種行為的原因是,如果您的 promise 鏈具有多個catch
塊,如下所示:
fetch(...)
.then(...)
.catch(...)
.then(...)
.then(...)
.catch(...);
然后,如果第一個catch
塊捕獲到任何鏈接在它之前的函數拋出的錯誤,那么這個catch
塊可以做以下兩件事之一:
catch
塊如果第一個catch
塊正常返回,則catch
塊返回的 promise 滿足該catch
塊的返回值,然后該值成為 ZB321DE3BDC299EC807E9F795D7 鏈中下一個then
塊的回調 function 的輸入。 因此,promise 鏈會繼續,而不是在第一個catch
塊執行后立即停止。
回到您的代碼,當catch
塊在backendService.ts
文件中的getTasks
方法中執行時,它會記錄消息並返回undefined
,然后導致調用Entries.tsx
文件中的then
塊,而不是catch
塊和這就是為什么您會收到 typescript 關於您的代碼的投訴。
解決方案
您可以使用以下選項之一來解決此問題:
拋出在backendService.ts
文件中getTasks
方法的catch(...)
塊中捕獲的錯誤,以便Promise
方法返回的getTasks
被拒絕,而不是用undefined
的值完成。
刪除backendService.ts
文件中getTasks
function 中的catch
塊,並在調用getTasks
方法的代碼中添加catch
塊。
在我看來,在backendService.ts
文件中不需要catch
塊,因為如果Promise
axios.get(...)
返回的getTasks
被拒絕, Promise
返回catch
方法也會被拒絕。 getTasks
方法。 因此,只需從getTasks
方法中刪除catch(...)
塊,然后在調用此getTasks
方法的位置添加catch(...)
塊。
有很多選項可以處理這個
Axios 在響應錯誤時不會崩潰,因此您必須正確檢查響應並處理它,因為它不應該只是盲目地破壞響應 object
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.