switchMap 运算符不执行返回的可观察对象

switchMap operator doesn't execute the returned observable

我有一个 API (NestJS) 并尝试建立登录。它正在使用 TypeOrm 访问数据库。

当策略 class 调用 auth.validateUser 方法时,我需要从数据库中获取用户并使用 bcrypt 比较密码。问题是 switchMap 没有订阅 returned observable。

这是我的代码:

auth.service.ts

validateUser(email: string, password: string): Observable<User> {
    return this.userService.readByEmail(email).pipe(
        switchMap(user => {
            return new Observable<User>(subscriber => {
                if (!user) {
                    subscriber.next(null)
                    subscriber.complete()
                } else {
                    bcrypt.compare(password + global.userPepper, user.password)
                        .then(result => {
                            const { password, ...validUser } = user
                            if (result) subscriber.next(validUser as User)
                            else subscriber.next(null)
                            subscriber.complete()
                        })
                        .catch(err => {
                            console.log(err)
                            subscriber.next(null)
                            subscriber.complete()
                        })
                }
            })
        })
    )
}

user.service.ts

readByEmail(email: string): Observable<User> {
    return new Observable<User>(subscriber => {
        // This part of the code is never executed
        this.userRepo.findOne({ email }).then(user => subscriber.next(user))
    })
}

问题是什么,我该如何解决?

更新:
userService.readByEmail 中的问题已根据 Tobias S. 回答中的建议得到解决。 但是来自 authServiceswitchMap 运算符没有被调用。我解决了它改变策略文件,它调用我的 auth.validateUser 到 return 承诺,不再是可观察的并且有效。
local.strategy.ts
之前:

validate(email: string, password: string) {
    return this.auth.validateUser(email, password).pipe(
        map(user => {
            if (!user) {
                throw new UnauthorizedException()
            }

            return user
        })
    )
}

之后:

validate(email: string, password: string) {
    return this.auth.validateUser(email, password).pipe(
        map(user => {
            if (!user) {
                throw new UnauthorizedException()
            }

            return user
        })
    ).toPromise()
}

我认为这段代码可以进一步简化。你真的不需要用 new Observable().

自己创建任何 Observables

在 UserService 中,您可以使用 from 运算符简单地从 Promise 创建一个 Observable。

user.service.ts

readByEmail(email: string): Observable<User> {
    return from(this.userRepo.findOne({ email }))
}

在 AuthService 中,如果没有用户,您可以 return EMPTY 然后 return 您正在使用 bcrypt 创建的 Promise。

"If it accepts Observable, it accepts Promise"

auth.service.ts

validateUser(email: string, password: string): Observable<User> {
    return this.userService.readByEmail(email).pipe(
        switchMap(user => {
            if (!user) return EMPTY

            return bcrypt.compare(password + global.userPepper, user.password)
                .then(result => {
                    const { password, ...validUser } = user
                    if (result) return validUser as User
                 })
                .catch(console.log)
        })
    )
}