【问题标题】:Subscribe to observable after http call. Angular 6在 http 调用后订阅 observable。角 6
【发布时间】:2019-04-27 02:27:07
【问题描述】:

这是我在 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 调用以获取新的配置文件。下面的代码订阅了获得的配置文件。

    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() 代码行之后延迟,以便当我订阅配置文件时,我的组件会看到它?

编辑:

只是为了清楚。 currentloginAttemp 在 this.loginService.signIn 进行 http 调用时分配。这就是为什么我不确定为什么 newProfileObj 在 this.profileService.getProfile() 方法中分配时为空。

编辑 2:

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

【问题讨论】:

  • 你能在stackbitz上发布一个可测试的代码,以便我们测试它
  • JD333 - 你解决了吗?

标签: angular typescript behaviorsubject


【解决方案1】:

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

在我的组件中,我创建了一个函数:

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

在进行第二次 http 调用后,我从上面调用了异步函数 ^:

    (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')
  })();

这很有效,虽然我不确定它是否是最好的解决方案。

【讨论】:

  • 我该怎么做?我想使用最小的延迟。但是,如果网络太慢会发生什么。我可以设置一个动态延迟,知道网络是否慢。
  • 您能否在 stackbitz 上发布一个最小的演示,以便我们准确找出问题所在。如果响应在延迟之后出现,您的解决方案将无法工作。所以这不是一个好的解决方案
  • 查看我提出的解决方案 - 它比这个更好,因为它等待事件而不管它何时发生而不是尝试计时。
【解决方案2】:

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

主题示例:

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

控制台输出将为空

行为主题示例:

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);
          }   
        });
  }

【讨论】:

  • 我正在使用行为主题
  • @JD333 请展示您的 getProfile 函数。这对我来说似乎是主题。您可能已经创建了不同的服务实例
  • 刚刚发布了
  • @JD333 我的意思是 newProfileObj 声明代码。为什么您在获取配置文件中有 currProfileObj 并且您已订阅 newProfileObj。为什么你对同一个主题使用不同的名字
  • currProfileObj 是主题。 newProfileObj 是可观察对象。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:
    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));
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      • 2019-07-14
      • 2018-11-23
      • 2017-11-30
      • 2021-01-20
      • 1970-01-01
      • 2020-08-10
      相关资源
      最近更新 更多