Kok*_*oko 33 promise typescript
我在Typescript中使用window.fetch,但我无法将响应直接转换为我的自定义类型:
我通过将Promise结果转换为中间的'any'变量来解决这个问题.
这样做的正确方法是什么?
import { Actor } from './models/actor';
fetch(`http://swapi.co/api/people/1/`)
.then(res => res.json())
.then(res => {
// this is not allowed
// let a:Actor = <Actor>res;
// I use an intermediate variable a to get around this...
let a:any = res;
let b:Actor = <Actor>a;
})
Run Code Online (Sandbox Code Playgroud)
Chr*_*ris 49
下面是一些示例,从基本到请求和/或错误处理后添加转换:
// Implementation code where T is the returned data shape
function api<T>(url: string): Promise<T> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json<T>()
})
}
// Consumer
api<{ title: string; message: string }>('v1/posts/1')
.then(({ title, message }) => {
console.log(title, message)
})
.catch(error => {
/* show error message */
})
Run Code Online (Sandbox Code Playgroud)
通常,您可能需要在将数据传递给使用者之前对数据进行一些调整,例如,展开顶级数据属性.这是直截了当的:
function api<T>(url: string): Promise<T> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json<{ data: T }>()
})
.then(data => { /* <-- data inferred as { data: T }*/
return data.data
})
}
// Consumer - consumer remains the same
api<{ title: string; message: string }>('v1/posts/1')
.then(({ title, message }) => {
console.log(title, message)
})
.catch(error => {
/* show error message */
})
Run Code Online (Sandbox Code Playgroud)
我认为你不应该直接在这个服务中直接捕获错误,而只是允许它冒泡,但如果你需要,你可以做以下事情:
function api<T>(url: string): Promise<T> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json<{ data: T }>()
})
.then(data => {
return data.data
})
.catch((error: Error) => {
externalErrorLogging.error(error) /* <-- made up logging service */
throw error /* <-- rethrow the error so consumer can still catch it */
})
}
// Consumer - consumer remains the same
api<{ title: string; message: string }>('v1/posts/1')
.then(({ title, message }) => {
console.log(title, message)
})
.catch(error => {
/* show error message */
})
Run Code Online (Sandbox Code Playgroud)
Rod*_*ati 13
实际上,在打字稿中的几乎任何地方,只要传递的类型兼容,将值传递给具有指定类型的函数就可以按需要工作。
话虽这么说,以下作品......
fetch(`http://swapi.co/api/people/1/`)
.then(res => res.json())
.then((res: Actor) => {
// res is now an Actor
});
Run Code Online (Sandbox Code Playgroud)
我想将所有 http 调用包装在一个可重用的类中 - 这意味着我需要某种方式让客户端以所需的形式处理响应。为了支持这一点,我接受回调 lambda 作为包装方法的参数。lambda 声明接受任何类型,如下所示......
callBack: (response: any) => void
Run Code Online (Sandbox Code Playgroud)
但在使用中,调用者可以传递指定所需返回类型的 lambda。我从上面修改了我的代码,如下所示......
fetch(`http://swapi.co/api/people/1/`)
.then(res => res.json())
.then(res => {
if (callback) {
callback(res); // Client receives the response as desired type.
}
});
Run Code Online (Sandbox Code Playgroud)
这样客户端就可以通过回调来调用它,例如......
(response: IApigeeResponse) => {
// Process response as an IApigeeResponse
}
Run Code Online (Sandbox Code Playgroud)
如果你看一下@types/node-fetch你会看到主体定义
export class Body {
bodyUsed: boolean;
body: NodeJS.ReadableStream;
json(): Promise<any>;
json<T>(): Promise<T>;
text(): Promise<string>;
buffer(): Promise<Buffer>;
}
Run Code Online (Sandbox Code Playgroud)
这意味着您可以使用泛型来实现您想要的目的。我没有测试这段代码,但它看起来像这样:
import { Actor } from './models/actor';
fetch(`http://swapi.co/api/people/1/`)
.then(res => res.json<Actor>())
.then(res => {
let b:Actor = res;
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45868 次 |
| 最近记录: |