为什么要触发Observable?

时间:2019-05-18 19:34:03

标签: javascript rxjs observable

我不明白为什么在可观察对象的末尾添加.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();
}

感谢您的时间和耐心

3 个答案:

答案 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 );

在诺言中也会发生同样的行为。回调函数需要一个函数而不是一个语句。