简体   繁体   English

Angular 使用 promise 和 generics 在 promise

[英]Angular using promise with generics inside promise

I need to interlace promises in my app:我需要在我的应用程序中交错承诺:

  protected scroll<T>(path: string, pageSize: number, filter: string, data: T[]): Promise<T[]> {    
            let promise = new Promise<T[]>(function(resolve, reject) {
                this.httpClient
                    .get<T[]>(this.appConfigService.buildApiUrl(path), { params })
                    .toPromise<T[]>()
                    .then(result => {
                        if (result) {
                            resolve(data.concat(result));
                        }
                    })
                    .catch(function(e) {
                        reject(e);
                    });
            });

            return promise;
        }

My problem is that I receive following message: 'Untyped function calls may not accept type arguments'我的问题是我收到以下消息:“未键入的 function 调用可能不接受类型参数”

How would I solve this?我将如何解决这个问题?

UPDATE:更新:

I should not have removed the if condition from the example:我不应该从示例中删除 if 条件:

  if (!filter) {
            const params = new HttpParams()
                .set('searchText', '')
                .set('skip', data.length.toString())
                .set('take', pageSize.toString());

            const promise = new Promise<T[]>((resolve, reject) => {
                this.httpClient
                    .get<T>(this.appConfigService.buildApiUrl(path), { params })
                    .toPromise<any>()
                    .then(result => {
                        if (result) {
                            resolve(data.concat(result));
                        }
                        resolve(data);
                    })
                    .catch(e => reject(e));
            });

            return promise;
        }
        // also returning a promise
        return this.filter<T>(data, pageSize, filter, path);

There are a couple of problems there.那里有几个问题。

  1. The error message is because you're using <T[]> on get and toPromise , which aren't generic functions.错误消息是因为您在gettoPromise上使用了<T[]> ,它们不是通用函数。 Just apply the type T to result in the then handler.只需应用类型T即可then result程序。

  2. You're falling into the promise creation antipattern.您陷入了 promise 创建反模式。 You already have a promise (from this.httpClient ), so you don't need new Promise .已经有一个 promise (来自this.httpClient ),所以你不需要new Promise

  3. You're using a traditional function for your new Promise callback, but then using this within it as though it were still referring to your class instance.您正在为new Promise回调使用传统的 function ,但随后在其中使用this ,就好像它仍然引用您的 class 实例一样。 If you were going to keep the new Promise , you'd want an arrow function instead, so it closes over this .如果您要保留new Promise ,则需要一个箭头 function ,所以它会关闭this .

Instead (see *** comments):相反(见***评论):

protected scroll<T>(path: string, pageSize: number, filter: string, data: T[]): Promise<T[]> {    
    // *** Return the result of calling `then` on the promise from `toPromise`
    return this.httpClient
        // *** Don't use <T[]> on `get` and `toPromise`
        .get(this.appConfigService.buildApiUrl(path), { params })
        .toPromise()
        .then((result: T) => { // *** <== Note the `T`
            // *** If it's really possible that `result` will be falsy and you don't want that
            // to be valid, you can do this:
            if (!result) {
                throw new Error("appropriate error here");
            }
            return data.concat(result);
        });
}

On the playground 在操场上


UPDATE:更新:

I should not have removed the if condition from the example:我不应该从示例中删除 if 条件:

It doesn't matter, just put the body of the above into the if block:没关系,把上面的body放到if块中即可:

protected scroll<T>(path: string, pageSize: number, filter: string, data: T[]): Promise<T[]> {    
    if (!filter) {
        const params = new HttpParams()
           .set('searchText', '')
           .set('skip', data.length.toString())
           .set('take', pageSize.toString());

        return this.httpClient
            // *** Don't use <T[]> on `get` and `toPromise`
            .get(this.appConfigService.buildApiUrl(path), { params })
            .toPromise()
            .then((result: T) => { // *** <== Note the `T`
                // *** If it's really possible that `result` will be falsy and you don't want that
                // to be valid, you can do this:
                if (!result) {
                    throw new Error("appropriate error here");
                }
                return data.concat(result);
            });
    }
    return this.filter<T>(data, pageSize, filter, path);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM