【问题标题】:return value in subscribe in angular以角度订阅的返回值
【发布时间】:2021-09-22 23:17:58
【问题描述】:

我是 Angular 新手,我已经搜索了很长时间

我有一个登录方法

login(email: string, password: string): Observable<any> {
    //return this.http.post<ServiceResponse>(API_USERS_URL, { email, password });
    debugger;
    
    this.http.post<ServiceResponse>(API_USERS_URL, { email, password }).subscribe((response: ServiceResponse) => {
        
      if (response.success) {
        const auth = new AuthModel();
        auth.accessToken = "access-token-8f3ae836da744329a6f93bf20594b5cc";
        auth.refreshToken = "access-token-f8c137a2c98743f48b643e71161d90aa";
        auth.expiresIn = new Date(Date.now() + 100 * 24 * 60 * 60 * 1000);
        return auth;
      }
    }, (error: ServiceResponse) => {
      console.log(error);
      return undefined;
    });
  }

我使用 subscribe 来检查响应是否成功,如果成功则返回值,如果不成功则返回 undefined 并记录错误

这里有一个编译错误,我应该返回值,当我在方法末尾添加return时,它在响应来自服务器之前返回

有人可以帮忙吗?

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    再次查看完整的代码示例后,我发现您想要返回一个 Observable。你暂时不退还那个。

    你可以创建一个 Observable,然后在观察者上调用 .next

    login(email: string, password: string): Observable<any> {
      return new Observable(observer => {
        this.http.post <ServiceResponse >(API_USERS_URL, { email, password }).subscribe((response: ServiceResponse) => {
              if (response.success) {
                const auth = new AuthModel();
                auth.accessToken = 'access-token-8f3ae836da744329a6f93bf20594b5cc';
                auth.refreshToken = 'access-token-f8c137a2c98743f48b643e71161d90aa';
                auth.expiresIn = new Date(Date.now() + 100 * 24 * 60 * 60 * 1000);
                observer.next(auth);
              }
              observer.next(null);
            },
            (error: ServiceResponse) => {
              console.log(error);
              observer.next(null);
            }
          );
      });
    }
    

    另外,除了订阅http.post,您还可以 return http.post().pipe(map());,让login的消费者做login().subscribe()

    login(email: string, password: string): Observable<any> {
        return this.http.post <ServiceResponse >(API_USERS_URL, { email, password }).pipe(map(response => {
          if (response.success) {
            const auth = new AuthModel();
            auth.accessToken = "access-token-8f3ae836da744329a6f93bf20594b5cc";
            auth.refreshToken = "access-token-f8c137a2c98743f48b643e71161d90aa";
            auth.expiresIn = new Date(Date.now() + 100 * 24 * 60 * 60 * 1000);
            return auth;
          }
          return null;
        }),
        catchError(err => {
          console.log(err);
          return undefined;
        }));    
    }
    

    Here is a minimal StackBlitz example of the second approach

    【讨论】:

    【解决方案2】:

    我认为您不需要 observable,但您可以使用 RxJs 运算符 of 返回 observable(该库已在您的项目中)

    import { of } from 'rxjs';
        //...
    return of(auth)
    

    或者带有行为主体

    new BehaviorSubject<any>(auth)
    

    但我认为这种情况下的好方法是返回Promise

    return new Promise<any>((resolve , reject) =>{
          if(login==true){ resolve(auth) }
          if(login==false){ reject() }
    })
    

    您的 HTTP 请求只会“发出”一次,这就是为什么不需要 observable 的原因。使用 WebSocket observable 可能会更有趣

    来自Promises vs Observable

    【讨论】:

    • 虽然这是真的,但 Observable 是 Angular 中执行单响应 REST 调用的惯用方式。无需承诺结果 - 如果构造正确,它将发出一次然后完成
    • @msanford 谢谢。当 HTTP 响应只响应一次时,我们为什么要使用 observable?
    • 正如我所提到的,因为它惯用方式 Angular 处理 REST 请求,这些请求(几乎所有)只响应一次。您将如何创建任何其他服务?当这样看时,我们注意到原始代码的 结构 是错误的,这也是为什么这个解决方案 即使承诺 不起作用的原因。提示:: Observable&lt;any&gt; 添加的返回类型注释 OP 是一个谎言,因为 login() 不返回任何内容。
    • 我正在阅读它,你是对的 - 他们说“保持一致性”可观察可用于管道和其他角度思考......显然承诺在引擎盖下转换为可观察跨度>
    • 这个“如何从订阅中获取值”的问题是 Rxjs 中的一个规范问题,并且有很多关于它的文章。然而,这还不是全部。只有 arrow functions have implicit return 在 JavaScript 中。 this.http.post...调用,但它不是从login()返回。为此,您需要 return this.http.post... 以便 login() 的调用者可以看到它。这就是为什么您一般在这里不订阅(),而是在调用者方法中订阅login()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 2017-01-10
    相关资源
    最近更新 更多