javascript - RXJS 对另一个可观察值进行过滤

标签 javascript typescript rxjs observable

在我的代码中,我从 MS Graph 获取用户列表,但这列出了所有用户。我只想发出属于指定组成员的用户。所以我设置了一个过滤器:

private loadUsers() {
    console.log(`Loading users...`);
    this.graph.get$(`users`)
        .map(resp => resp.json().value)
        .flatMap(user => user)
        .do(user => {
            console.log(`Got user: ${user['displayName']}`);
        })
        .filter(user => {
            // we only want users who are members of the TrackerContact group
            const userId: string = user['id'];
            console.log(`Checking user ${userId}`);
            return this.userIsTrackerContact(user); // <<= PROBLEM HERE!
        })
        .subscribe(_ => {
            console.log(`Completed user fetch!`);
        });
}

问题是为了找出用户所属的组,我必须再次进行 REST 调用 MS Graph :

private userIsTrackerContact(user): Observable<boolean> {
    // get the groups this user is a member of
    return this.graph.get$(`users/${user['id']}/memberOf`)
        .map(resp => resp.json().value)
        .do(groups => {
            console.log(`${user['displayName']} is a member of ${groups.length} groups:`);
            groups.forEach((group, idx) => {
                console.log(`   [${idx+1}]: ${group['displayName']}`);
            })
        })
        .map(groups => {
            const found = groups.find((group) => group['id'] === this.authConfig.azureGroups.trackerContact)
            return !isUndefined(found);
        })
}

在我看来不可能 filter一个基于另一个可观察值的可观察值。谓词测试必须是简单的真/假测试。

如何根据另一个 Observable 的结果过滤一个 Observable?

最佳答案

.concatAll() 可能会更好:

this.graph.get$(`users`)
    .map(resp => resp.json().value)
    .flatMap(user => user)
    .do(user => {
        console.log(`Got user: ${user['displayName']}`);
    })
    .filter(user => {
        // we only want users who are members of the TrackerContact group
        const userId: string = user['id'];
        console.log(`Checking user ${userId}`);
        return this.userIsTrackerContact(user); // <<= PROBLEM HERE!
    })
    .concatAll()
    .subscribe(...)

我相信你应该能够merge然后过滤异步可观察量。

Rx.Observable.merge(this.graph.get$(`users`)
    .map(resp => resp.json().value)
    .flatMap(user => user)
    .do(user => {
        console.log(`Got user: ${user['displayName']}`);
    })
    .map(user => {
        // we only want users who are members of the TrackerContact group
        const userId: string = user['id'];
        console.log(`Checking user ${userId}`);
        return this.userIsTrackerContact(user); // <<= PROBLEM HERE!
    }))
    .filter(x => x)
    .subscribe(_ => console.info('success'));

您可以更改用户 isGroupMember 上的谓词设置属性。然后filter(x => x.isGroupMember)。然后你就可以在订阅方法中获得用户对象。

关于javascript - RXJS 对另一个可观察值进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42726556/

相关文章:

javascript - onclick 表 TD

reactjs - Prop 的 TypeScript 条件类型

angular - 如何使用事件发射器触发子组件和父组件中的函数?

angular - 确保最后一个 http post 在 Angular 中最后到达后端

javascript - 如何在 Rx.Observable 上链接订阅? (重构)

javascript - 如何在创建 Observer 时强制评估 Observer 中的表达式,而不是在发出值时

javascript - HTML5 Canvas 描边具有一致的 alpha 值

javascript - 数据以凌乱的方式加载到页面上

javascript - 遍历 jsPlumb 中 div 的端点

javascript - 在函数内部使用公共(public)变量