rxjs重试时不总是触发

时间:2016-02-11 13:33:11

标签: javascript typescript rxjs

我有一个应用程序,它使用来自Google的javascript授权API的令牌进行身份验证。我有一个函数请求,可以为我提出所有请求。当我的令牌过期时,我想在retryWhen块中刷新它,然后重试失败的调用。

request<T>(args:{ path: string, params?: any }):Rx.Observable<T> {
    console.log( `make request for: ${args.path}` );

    return this.loadClientDetails()
        .flatMap<T>( clientDetails => {
            console.log( `creating request for: ${args.path}` );
            const request:HttpRequest<T> = gapi.client.request(args);
            return Rx.Observable.fromPromise<IHasResult<T>>( <any>request)
                .map( result => { return result.result } );
            }
        )
        .retryWhen( errors => {

            return errors.flatMap( currentError => {

                console.log( `Error status: ${currentError.result.error.code}` );

                if(currentError.result.error.code == 401) {
                    console.log( `not authorized, attempting auth for ${args.path}` );
                    if( !this.refreshToken ) {
                        console.log( `creating refresh token for ${args.path}` );
                        this.refreshToken = this.askForAuthentication( this.clientDetails,this.authorizationScopes, true)
                            .do( _ => {
                                console.log( `refresh token complete ${args.path}` );
                                this.refreshToken = null;
                            } ).shareReplay(1);
                    } else {
                        console.log( `returning existing refresh token for ${args.path}` );
                    }

                    return this.refreshToken;
                }

                return Rx.Observable.throw( currentError );
            } )
            .do(
                _ => {console.log(`flatmap onNext for ${args.path}`)},
                _ => {console.log(`flatmap error for ${args.path}`)},
                () => {console.log(`flatmap complete for ${args.path}`)}
        );
        } )
        .do(
          _ => {console.log(`result returned for path: ${args.path}`)},
          error => { console.log( `error returned for path: ${args.path} Error: ${error}` ) }
        );
}

所以:

  1. loadClientDetails确保从json文件
  2. 加载应用程序的客户端ID
  3. 然后我们使用flatMap创建一个实际加载数据的observable
  4. 重试当确定错误是否是由于权限到期(状态401)
  5. 如果是,它会创建一个observable来请求新的身份验证来刷新令牌
  6. 如果已存在refreshToken流,则只返回该内容并共享结果
  7. 如果错误不是权限问题,则只会抛出原始错误
  8. 这一切似乎都在起作用,但我的2次调用中只有一次失败了。在启动时,该应用程序加载userInfo和cahnnels:

    我得到的日志是:

    make request for: https://www.googleapis.com/youtube/v3/channels
    googleAuthenticationService.ts:105 creating request for: https://www.googleapis.com/youtube/v3/channels
    googleAuthenticationService.ts:95 make request for: https://www.googleapis.com/oauth2/v2/userinfo
    googleAuthenticationService.ts:105 creating request for: https://www.googleapis.com/oauth2/v2/userinfo
    googleAuthenticationService.ts:115 Error status: 401
    googleAuthenticationService.ts:118 not authorized, attempting auth for https://www.googleapis.com/oauth2/v2/userinfo
    googleAuthenticationService.ts:120 creating refresh token for https://www.googleapis.com/oauth2/v2/userinfo
    googleAuthenticationService.ts:166 Asking for authentication: 951450855116-36vi2ec5eo6m2972oke8k4l7tp29irrn.apps.googleusercontent.com
    googleAuthenticationService.ts:115 Error status: 401
    googleAuthenticationService.ts:118 not authorized, attempting auth for https://www.googleapis.com/youtube/v3/channels
    googleAuthenticationService.ts:127 returning existing refresh token for https://www.googleapis.com/youtube/v3/channels
    googleAuthenticationService.ts:171 authorisation granted
    googleAuthenticationService.ts:123 refresh token complete https://www.googleapis.com/oauth2/v2/userinfo
    googleAuthenticationService.ts:136 flatmap onNext for https://www.googleapis.com/oauth2/v2/userinfo
    googleAuthenticationService.ts:105 creating request for: https://www.googleapis.com/oauth2/v2/userinfo
    googleAuthenticationService.ts:136 flatmap onNext for https://www.googleapis.com/youtube/v3/channels
    commentatorController.ts:75 loading all comment threads: 386.773ms
    googleAuthenticationService.ts:142 result returned for path: https://www.googleapis.com/oauth2/v2/userinfo
    headerController.ts:43 User info loaded
    

    我可以看到重试中的flatmapWhen为两个调用触发,因为两个行都有一个flatMap onNext行。

    关于这里出了什么问题以及为什么其中一个电话永远不会重试的任何想法? 感谢

0 个答案:

没有答案