使用 tap() 而不是 map() RxJS 和 Angular
Use tap() instead of map() RxJS and Angular
我有一个登录守卫,主要检查用户是否登录。如果他登录了,它会跳过登录并转到主页。我写了这段代码,效果很好:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.store.select(fromApp.isAuthenticated)
.pipe(take(1),
map(isAuthenticated => {
if (isAuthenticated) {
this.router.navigate(['/home']);
return false;
} else {
return true;
}
})
)
}
现在,由于我不必更改或编辑输出数据(isAuthenticated 布尔值),我想:好吧,为什么不使用 tap 运算符?所以,我重写了我的代码:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.store.select(fromApp.isAuthenticated)
.pipe(take(1),
HERE------> tap(isAuthenticated => { <------ HERE
if (isAuthenticated) {
this.router.navigate(['/home']);
return false;
} else {
return true;
}
})
)
}
然后我去了Chrome,看到黑页是这样的:
- 我打开应用程序
- 我没有登录
- url 变为 http://localhost:4200/#/ 而不是
http://localhost:4200/#/login,结果:空白页
- 如果我尝试在 http://localhost:4200/#/login 中手动进入,它会停留在
该页面,但我看到一个空白页面
- 如果我想回家,它会重定向到 http://localhost:4200/#/
共 http://localhost:4200/#/login
无论如何,我看到的是空白页。所以,我进行了调试,我注意到它正确地跳入了 if/else 块内……那么,为什么 tap() 会破坏应用程序?
This是canActivate
的签名:
interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
}
canActivate
必须 return boolean
或 Promise
。因此你必须map
它和return一个boolean
或Promise
。 tap
不会成功。
守卫 canActivate
必须 return 一个 Observable<boolean>
才能使 Angular 守卫机制工作。
使用 map
允许您定义一个 return,它不同于您从 isAuthenticated
得到的,这可能解释了您所看到的。
在你的第一个版本中 canActivate
实际上 return 是一个 Observable<boolean>
- 在第二种情况下它 return 是这个 this.store.select(fromApp.isAuthenticated).pipe(take(1))
,并且可能是不是你想要的。
我有一个登录守卫,主要检查用户是否登录。如果他登录了,它会跳过登录并转到主页。我写了这段代码,效果很好:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.store.select(fromApp.isAuthenticated)
.pipe(take(1),
map(isAuthenticated => {
if (isAuthenticated) {
this.router.navigate(['/home']);
return false;
} else {
return true;
}
})
)
}
现在,由于我不必更改或编辑输出数据(isAuthenticated 布尔值),我想:好吧,为什么不使用 tap 运算符?所以,我重写了我的代码:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.store.select(fromApp.isAuthenticated)
.pipe(take(1),
HERE------> tap(isAuthenticated => { <------ HERE
if (isAuthenticated) {
this.router.navigate(['/home']);
return false;
} else {
return true;
}
})
)
}
然后我去了Chrome,看到黑页是这样的:
- 我打开应用程序
- 我没有登录
- url 变为 http://localhost:4200/#/ 而不是 http://localhost:4200/#/login,结果:空白页
- 如果我尝试在 http://localhost:4200/#/login 中手动进入,它会停留在 该页面,但我看到一个空白页面
- 如果我想回家,它会重定向到 http://localhost:4200/#/ 共 http://localhost:4200/#/login
无论如何,我看到的是空白页。所以,我进行了调试,我注意到它正确地跳入了 if/else 块内……那么,为什么 tap() 会破坏应用程序?
This是canActivate
的签名:
interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
}
canActivate
必须 return boolean
或 Promise
。因此你必须map
它和return一个boolean
或Promise
。 tap
不会成功。
守卫 canActivate
必须 return 一个 Observable<boolean>
才能使 Angular 守卫机制工作。
使用 map
允许您定义一个 return,它不同于您从 isAuthenticated
得到的,这可能解释了您所看到的。
在你的第一个版本中 canActivate
实际上 return 是一个 Observable<boolean>
- 在第二种情况下它 return 是这个 this.store.select(fromApp.isAuthenticated).pipe(take(1))
,并且可能是不是你想要的。