我不明白为什么在可观察对象的末尾添加.take(1)会触发结果,如果我不这样做,它会一直处于待处理状态:
function generateToken(identifier){
return new Observable<string>((observer) => {
jwt.sign(identifier, 'devsecret', (err, token) => {
if (err) {
observer.error(err);
} else if (token) {
observer.next(token);
}
});
}).pipe( take(1));
}
有人知道为什么吗?希望分享原因以及这是否是正确的实施方式?请注意,我没有在其他任何地方订阅此功能,但我一直在传递结果。
在这里我调用该方法并返回带有授权标头的响应
public login(identifier): Observable<any> {
return generateToken(identifier).pipe(
catchError((err: Error) => of(err)),
map(token => {
return {'Authorization': token}
}));
}
最后但并非最不重要的一点是,此函数将转换为Promise,并将响应作为http请求返回
function async userLogin(identifier) {
return await login(identifier).toPromise();
}
感谢您的时间和耐心
答案 0 :(得分:1)
这说明了您的问题:
return await login(identifier).toPromise();
Promise决定Observable完成或在出错时拒绝,因此它与take(1)
一起使用,因为它采用第一个Observable值并将其完成。
完成后,您还可以获取输出。而且看起来更合适:
} else if (token) {
observer.next(token);
observer.complete(); <---
}
答案 1 :(得分:1)
take(1)
确保在发出第一项后立即调用subscriber.complete()
方法。顺便说一句,可以直接在observer.complete()
之后调用observer.next()
来完成此操作。
toPromise()
仅在流完成后解析,而不是在每次发射时解析。
答案 2 :(得分:0)
尝试
.pipe( () => take(1) );
或
.pipe( take );
在诺言中也会发生同样的行为。回调函数需要一个函数而不是一个语句。