如何将 Angular $http 与 typescript 泛型一起使用

Posted

技术标签:

【中文标题】如何将 Angular $http 与 typescript 泛型一起使用【英文标题】:How to use Angular $http with typescript generics 【发布时间】:2017-01-11 23:45:03 【问题描述】:

我正在尝试通过以下方式返回通用承诺

public getUserPreferences: () => ng.IPromise <string> = () => 
        var promise = this.makeRequest<string>('http://someurl.com',null)
            .then((response:string) => 
                    let res: string = response;
                    return res;
                
            )
            .catch((error) => 
            );

        return promise;
    ;

        public makeRequest<T>(וrl: string, data?: any,
                          config?: any, verb?: HttpMethod): ng.IPromise<T> 
        // Cache key contains both request url and data
        var cacheKey = url + '*' + JSON.stringify(data);

        var deferred = this.$q.defer();
        var httpRequest: any;
        var responseData: T;
        var start = new Date().getTime();

        // Trying to retrieve cache data if needed
        if (!config || config.cache != false) 
            responseData = this.cacheService.get(cacheKey);
        

        if (responseData) 
            deferred.resolve(responseData);
        
        else 
            switch (verb) 
                case HttpMethod.GET:
                    httpRequest = this.$http.get(url, config);
                    break;
                case HttpMethod.POST:
                    httpRequest = this.$http.post(url, data, config);
                    break;
                case HttpMethod.PATCH:
                    httpRequest = this.$http.patch(url, data, config);
                    break;
                default:
                    httpRequest = this.$http.post(url, data, config);
                    break;

            

            httpRequest
                .then((res: any) => 
                    responseData = res.data;
                    this.cacheService.put(cacheKey, responseData);
                    deferred.resolve(responseData);
                )
                .catch((error: any) => 
                    deferred.reject(error);
                );
        

        return deferred.promise;
    

但我在 getUserPreferences 上收到以下错误:

错误:(132, 9) TS2322: 类型 '() => IPromise' 不可分配 输入'() => IPromise'。类型 'IPromise' 不是 可分配给类型“IPromise”。类型 'void' 不可分配 输入“字符串”。

【问题讨论】:

getUserPreferences删除catch块 @AlekseyL。谢谢!有用!但是我怎样才能捕捉到异常呢? 如果这是处理异常的正确位置并且您不想在异常情况下返回任何内容 - 您应该将返回类型定义为ng.IPromise &lt;string|void&gt;。请注意,如果您在此处捕获异常,则承诺将始终成功解决。 【参考方案1】:

看起来问题是你永远不会用responseData 解决promise:没有resolve(responseData) 意味着promise 是用undefined 隐式解决的。

试试这个:

public makeRequest<T>(url:string, data?: any): ng.IPromise<T> 
    return this.$http.post(url, data)
           .then((res: any) => 
               return res.data;
           );

我还删除了多余的延迟对象,你不需要,因为你可以直接返回承诺。

另一个区别。我放弃了catch 块,因为最好将它放在承诺链的末尾(在getUserPreferences 中)。

【讨论】:

我真正的 makeRequest 方法更复杂,因为首先我试图从缓存中检索值,如果它在缓存中不存在我想将它添加到缓存中,然后才发送响应,我将更新我的问题

以上是关于如何将 Angular $http 与 typescript 泛型一起使用的主要内容,如果未能解决你的问题,请参考以下文章

Angular 1.x 与 TypeScript 2.x、@types 和 SystemJS - 使用全局类型

如何在 Angular 2 项目中使用 types/select2?

如何从 Angular 2 响应中获取所有标头?

使用 @types/angular 作为全局

Django + Angular:如何将 angularjs $http 数据或参数发送到 django 并在 django 中解释?

Angular 6:无法正确设置 http Header 的 Content-Type