将 Injectable 服务函数作为回调函数参数传递

Passing an Injectable service function as a callback function parameter

提问人:ytan11 提问时间:10/25/2023 最后编辑:ytan11 更新时间:10/26/2023 访问量:27

问:

我试图实现的是首先获取数据,然后获取同步详细信息,以决定何时应该再次获取数据。在这里,我省略了逻辑的细节,因为这不是问题的原因。

问题是当我尝试将 Injectable 服务函数作为回调函数参数传递时。

当它被执行时,它说:ERROR Error: Cannot read properties of undefined (reading 'http')

这让我相信在我调用回调时没有注入 HttpClient。

将可注入服务函数作为回调函数参数传递是否不正确? 有什么办法可以克服这个问题吗?

Stackblitz 上的代码

export class DataComponent implements OnInit {
  constructor(
    private dataService: DataService,
    private syncService: SyncService
  ) {}

  ngOnInit(): void {
    this.getData().subscribe();
  }

  getData() {
    return this.dataService.getData().pipe(
      tap((res) => console.log('get first data', res)),
      switchMap(() =>
        this.syncService.getSync(this.dataService.getSyncDetails, this.getData)
      )
    );
  }
}
@Injectable({
  providedIn: 'root',
})
export class SyncService {
  constructor() {}

  getSync(syncService: Function, callbackService: Function): Observable<any> {
    console.log('getSync');
    return syncService().pipe(
      tap((res) => console.log('get sync data', res)),
      switchMap(() => callbackService())
    );
  }
}
@Injectable({
  providedIn: 'root',
})
export class DataService {
  constructor(private http: HttpClient) {}

  getData(): Observable<any> {
    console.log('getData');
    return this.http.get('https://reqres.in/api/users');
  }

  getSyncData(): Observable<any> {
    console.log('getSyncData');
    return this.http.get('https://regres.in/api/unknown/2');
  }
}
Angular 依赖注入 rxjs 回调

评论

1赞 TotallyNewb 10/26/2023
一本关于行为方式以及为什么你会失去上下文的好书:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/......this

答:

0赞 MoxxiManagarm 10/26/2023 #1

您仅提供一个函数,该函数会切换函数的上下文。若要保留服务上下文,可以在传递函数时将函数绑定到服务。

getData() {
    return this.dataService.getData().pipe(
      tap((res) => console.log('get first data', res)),
      switchMap(() =>
        this.syncService.getSync(this.dataService.getSyncDetails.bind(this.dataService), this.getData)
      )
    );
  }