制作链式可观察订阅的正确方法

时间:2017-05-06 02:09:15

标签: angular typescript rxjs

使用 RxJS 以反应方式重写此代码的更好方法是什么。



profileInformation;
updateProfile() {
let token;
let profileId = 1;
this.userService.getAccessToken()
    .map((res) => {
        //as I need it multiple times
        token = res;
        return res
    })
    .switchMap(accessToken => this.profleService.getContactIds(accessToken, profileId))
    .subscribe((res) => {
        this.profleService.updateprofile(token, this.profileInformation, res.account.id, res.address.id)
            .subscribe((data) => {
                console.log(data);
                //do stuff with data
            }, (err) => {
                //do something when err
            })
    }, (err) => {
        //do something when err
    });
})
}




3 个答案:

答案 0 :(得分:2)

您可以再次执行switchMap

this.userService.getAccessToken()
  .do(accessToken => token = accessToken)
  .switchMap(accessToken => this.profleService.getContactIds(accessToken, profileId))
  .switchMap(res => this.profleService.updateprofile(token, this.profileInformation, res.account.id, res.address.id))
  .subscribe(
    (data) => {
      console.log(data)
    }, (err) => {
    });

答案 1 :(得分:2)

updateProfile() {
  let token;
  const profileId = 1;

  this.userService.getAccessToken()
    .do(accessToken => token = accessToken)
    .switchMap(accessToken => this.profleService.getContactIds(accessToken, profileId))
    .flatMap(({account, address}) => this.profleService.updateprofile(token, this.profileInformation, account.id, address.id))
    .subscribe(data => {
      console.log(data);
      //do stuff with data
    }, err => {
      //do something when err
    });
}

我选择flatMap超过一秒switchMap的原因是这样的 switchMap传播发出值的第一个成分Observable。在原始代码中,您使用的是嵌套subscribe,其下一个处理程序将为内部Observable生成的每个值执行一次。 flatMap(AKA mergeMap)通过访问在仍然需要时可能发出的所有值来保留原始语义。

注意,如果只发出一个值,这无关紧要,但语义上一个observable可以发出很多值,我想保留它。我也相信它更清楚。

如果您对传递给flatMap

的投影函数中使用的语法感到好奇
(({account, address}) => 
  this.profleService.updateprofile(token, this.profileInformation, account.id, address.id)

它被称为ES2015参数解构。它用于直接从参数中提取属性到局部变量。我假设accountaddress属于res的属性的原因是无条件访问它们。这种语法在回调和一般投影函数中通常很有用。

考虑:

interface Entity {
  id: number;
}

declare const entities: Entity[];

function getById(entityId: number) {
  return entities.find(({id}) => id === entityId);
}

答案 2 :(得分:0)

我结束了这两个答案中最好的结合@juliapassynkova和@aluanhaddad



profileInformation;
updateProfile() {
    let token;
    let profileId = 1;
    this.userService.getAccessToken()
        //for multiple using token
        .do(accessToken => token = accessToken)
        .switchMap(accessToken => this.profleService.getContactIds(accessToken, profileId))
        .switchMap(res => this.profleService.updateprofile(token, this.profileInformation, res.account.id, res.address.id))
        .subscribe((data) => {
            console.log(data);
            //do stuff with data
        }, (err) => {
            //do something when err
        })
}