等待打字稿

时间:2017-11-19 18:56:47

标签: typescript es6-promise

我最近跳进了Angular2,我来自c#背景。我目前正在做"数据服务层"在客户端内,自然我按照我在ac#项目中的方式做到这一点......(所以,如果我做错了什么,请告诉我)。

我的结构是这样的:

  1. 数据服务 DataService(将响应从WS映射到指定类型T的通用数据服务)。这包括get,post和put函数。

  2. 博客服务 BlogService扩展了DataService,这将是例如BlogListComponent将使用的服务。

  3. 我也会使用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在异步函数返回任何内容之前没有点击它的返回语句,所以我认为我正在接近某些东西。

    无论如何,我最有可能在这里做一些根本错误的事情。我希望我能听到你是如何实现类似的东西的。

    感谢沮丧的新手!

1 个答案:

答案 0 :(得分:0)

  

尝试2:这是异步的本质,所以我会告诉函数等待Promise使用await关键字返回。

await super.post<Array<BlogPost>>(BlogDataService.GET_BLOGPOSTS_ENDPOINT, request).then(b => blogPosts = b);
     

然后编译器发出一个巨大的错误,说我不能在异步函数中将一个blogpost数组作为返回类型。

正确 - 因为async函数始终返回承诺,因此如果GetBlogPostsasync,则必须返回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);
}
  1. 这可能是也可能不是问题,具体取决于this.handleError的作用。如果它返回被拒绝的承诺,请跳至下面的#2。如果不是:通常,使用promises, 返回链,处理错误,但不能同时处理两者。如果同时执行这两项操作,请务必确保不将拒绝转换为不适当的解决方案。请记住,thencatch处理程序会创建一个新的承诺,根据他们的行为解决/拒绝承诺。

  2. 当你在async函数中时,使用promise回调并不是惯用的。从报告中删除async,或使用await(可能try / catch)。

  3. 如果您保留async,那么执行此操作可能更为惯用:

    protected async processResponse<T>(response : Observable<Response>) : Promise<T> {
        return await response.map(response => this.extractJson(response)).toPromise();
    }
    

    ...我们再次将错误处理留给调用者。