我最近跳进了Angular2,我来自c#背景。我目前正在做"数据服务层"在客户端内,自然我按照我在ac#项目中的方式做到这一点......(所以,如果我做错了什么,请告诉我)。
我的结构是这样的:
数据服务 DataService(将响应从WS映射到指定类型T的通用数据服务)。这包括get,post和put函数。
博客服务 BlogService扩展了DataService,这将是例如BlogListComponent将使用的服务。
我也会使用rgnx-store,但我现在暂时不考虑这个问题。
现在代码。
这是来自DataService。
protected post<T>(endpointUrl: string, request: object) : Promise<T> {
return this.processResponse<T>(this.http.post(endpointUrl, JSON.stringify(request), this.options()));
}
protected async processResponse<T>(response : Observable<Response>) : Promise<T> {
return response.map(response => this.extractJson(response))
.toPromise()
.catch(this.handleError);
}
尝试1:我的第一次尝试 - 我自然认为这样可行,但肯定没有。
public GetBlogPosts(request : GetBlogPostsRequest) : Array<BlogPost> {
var blogPosts: Array<BlogPost> = [];
super.post<Array<BlogPost>>(BlogDataService.GET_BLOGPOSTS_ENDPOINT, request).then(b => blogPosts = b);
return blogPosts;
}
这里发生的是我可以看到DataService设法将响应映射到一组博客帖子,但是
return blogPosts;
进入
之前b => blogPosts = b
所以我只返回一个空数组。
尝试2:这是异步的本质,所以我会告诉函数等待Promise使用await关键字返回。
await super.post<Array<BlogPost>>(BlogDataService.GET_BLOGPOSTS_ENDPOINT, request).then(b => blogPosts = b);
然后编译器发出一个巨大的错误,说我不能在异步函数中有一个blogposts数组作为返回类型。
尝试3:然后我删除了GetBlogPosts的异步声明,因为我真的想要返回一个BlogPost数组而不是将其更改为任何数组,并添加了一个嵌套函数,这是一个异步函数。
var s = () => super.post<Array<BlogPost>>(BlogDataService.GET_BLOGPOSTS_ENDPOINT, request).then(b => blogPosts = b);
async function awaiter(asyncFunction) : Promise<any> {
await asyncFunction;
}
这与代码看起来很不错 - 完全没有!虽然我可以看到GetBlogPosts在异步函数返回任何内容之前没有点击它的返回语句,所以我认为我正在接近某些东西。
无论如何,我最有可能在这里做一些根本错误的事情。我希望我能听到你是如何实现类似的东西的。
感谢沮丧的新手!
答案 0 :(得分:0)
尝试2:这是异步的本质,所以我会告诉函数等待Promise使用await关键字返回。
await super.post<Array<BlogPost>>(BlogDataService.GET_BLOGPOSTS_ENDPOINT, request).then(b => blogPosts = b);
然后编译器发出一个巨大的错误,说我不能在异步函数中将一个blogpost数组作为返回类型。
正确 - 因为async
函数始终返回承诺,因此如果GetBlogPosts
为async
,则必须返回Promise<Array<BlogPost>>
,而不是Array<BlogPost>
。< / p>
然后当然,使用 GetBlogPosts
的东西必须知道如何处理通过promise以异步方式从中获取数据。
您希望传播异步结果,直到您处于处理结果异步的事实的层,这通常意味着进入代码的入口点(事件处理程序等)。此时,您将使用非async
函数then
(处理成功)和catch
(处理错误)。所以GetBlogPost
要么就是那个位置,要么它应该将承诺返回给它的调用者,这样它的调用者(或者它的调用者等)就可以成为那个位置。
旁注:这里至少有一个,可能还有两个问题:
protected async processResponse<T>(response : Observable<Response>) : Promise<T> {
return response.map(response => this.extractJson(response))
.toPromise()
.catch(this.handleError);
}
这可能是也可能不是问题,具体取决于this.handleError
的作用。如果它返回被拒绝的承诺,请跳至下面的#2。如果不是:通常,使用promises, 返回链,或处理错误,但不能同时处理两者。如果同时执行这两项操作,请务必确保不将拒绝转换为不适当的解决方案。请记住,then
和catch
处理程序会创建一个新的承诺,根据他们的行为解决/拒绝承诺。
当你在async
函数中时,使用promise回调并不是惯用的。从报告中删除async
,或使用await
(可能try
/ catch
)。
如果您保留async
,那么执行此操作可能更为惯用:
protected async processResponse<T>(response : Observable<Response>) : Promise<T> {
return await response.map(response => this.extractJson(response)).toPromise();
}
...我们再次将错误处理留给调用者。