http通话后订阅观察者。角度6

时间:2018-11-25 02:49:19

标签: angular typescript behaviorsubject

这是我在Angular中遇到的一个问题。下面的方法进行两个http调用。

  submit(username: string, pword: string) {
    this.loginService.signIn(username, pword);

    this.loginService.currentloginAttemp.subscribe(data => {
      if (data == true) {
        this.profileService.getProfile();    
      }
    });

    this.profileService.newProfileObj.subscribe(dataProfile =>{
      console.log(dataProfile);
    });
  }

  submit(username: string, pword: string) {
    this.loginService.signIn(username, pword);

signIn进行http调用,并将其分配给可观察到的称为currentloginAttemp

    this.loginService.currentloginAttemp.subscribe(data => {
      if (data == true) {
        this.profileService.getProfile();    
      }
    });

上面的代码可以正常工作。 this.profileService.getProfile()进行http调用以获取新的Profile。以下代码订阅了所获得的配置文件。

    this.profileService.newProfileObj.subscribe(dataProfile =>{
      console.log(dataProfile);
    });
  }

当我做console.log(dataProfile);我收到未定义的警告。

当我运行此功能时:

  logout() {
        this.profileService.newProfileObj.subscribe(dataProfile =>{
          console.log(dataProfile);
        });
  }

console.log(dataProfile)返回一个配置文件。

如何延迟代码行 this.profileService.getProfile(),以便在我订阅配置文件时,我的组件可以看到它?

编辑:

请明确。当this.loginService.signIn进行http调用时,将分配currentloginAttemp。这就是为什么我不确定在方法this.profileService.getProfile()中分配newProfileObj时为什么为null的原因。

编辑2:

  getProfile() {
    let tempURL = this.getProfileUrl + this.currProfileId.value;
    this.http.get<Profile>(tempURL).subscribe((data) => {
      this.currProfileObj.next(data);
    });
  }

4 个答案:

答案 0 :(得分:1)

您的问题是您正在使用BehaviorSubject,并且每次发出.next()时,它都会立即发出。请参阅有关BehaviorSubject如何工作的文档here。因此,您通常会希望跳过第一个发射,因为您实际上只关心其余的发射。在您的情况下,这看起来像是这样(在rxjs 6+中):

this.profileService.newProfileObj.pipe(skip(1)).subscribe(dataProfile =>{
  console.log(dataProfile);
});

答案 1 :(得分:0)

这是一个解决方案。但是,我不确定这是否是最佳解决方案。

我在组件内部创建了一个函数:

  async delay(ms: number) {
    return new Promise( resolve => setTimeout(resolve, ms) );
  }

第二次http调用后,我从^上方调用了异步functino:

    (async () => { 
      // Do something before delay
      console.log('before delay')

     await this.delay(2000);
      this.profileService.newProfileObj.subscribe(dataProfile =>{
        console.log(dataProfile);
      // Do something after
      console.log('after delay')
  })();

这行得通,尽管我不确定这是否是最佳解决方案。

答案 2 :(得分:0)

我认为您正在使用主题。您应该使用BehaviorSubject而不是subject。主题没有价值。

主题示例:

const subject = new Rx.Subject();
subject.next(1);
subject.subscribe(x => console.log(x));

控制台输出将为空

BehaviorSubject示例:

const subject = new Rx.BehaviorSubject();
subject.next(1);
subject.subscribe(x => console.log(x));

控制台输出:1

BehaviorSubject可以使用初始值创建:new Rx.BehaviorSubject(1)

如果您不想使用上述方法,也可以尝试一下。

 this.profileService.newProfileObj.subscribe(dataProfile =>{
        if (dataProfile) {
            console.log(dataProfile);
          }   
        });
  }

答案 3 :(得分:-1)

getxTaskXCall()
     getxTask()
      .subscribe(
        success => {
         processFn(success);
        },
        error => {
          // this.errors = error;
        },
        () => {

        }
      );
       getxTask(tId: string, parameters: Array<number>): Observable<[string]> {
        return this.apiService.get(getUrl + tId + '/' + parameters)
            .pipe(map(data => data));
    }

 get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
    return this.http.get(`${api_url}${path}`, { params })
      .pipe(catchError(this.formatErrors));
  }