组件调用Service的SDK方法时如何获取异步回调返回的响应数据
你遇到的问题本质是回调风格的异步API无法直接被async/await捕获,因为sdk.publishToChannel执行后会立即返回,回调函数是后续异步触发的,所以直接返回它的返回值是拿不到回调里的response的,以下是两种成熟的解决方案:
方案1:封装为Promise(适配现有async/await写法,单次调用场景最推荐)
修改Service.ts代码
publishStream(publishCapabilities, mediaConstraints): Promise<any> { this.session = session; const videoElement = document.getElementsByTagName('video')[0]; const publishOptions = { publishToken: publishing, mediaConstraints: mediaConstraints, videoElement: videoElement }; // 将回调逻辑包装为Promise返回 return new Promise((resolve, reject) => { this.sdk.publishToChannel(publishOptions, (error, response) => { if (error) { this.logger.log(error); reject(error); // 抛出错误给调用方捕获 return; } this.callbackResponse = response; resolve(response); // 回调完成后返回结果 }); }) }
组件侧补充错误捕获即可,原有写法无需大幅调整:
async publishSession() { try { const publishCallback = await this.myService.publishStream(); // 此处已拿到回调返回的结果,直接处理业务逻辑即可 console.log('发布结果', publishCallback); } catch (error) { // 自定义发布失败的处理逻辑 console.error('发布失败', error); } }
方案2:RxJS Subject实现(适合多组件监听、需要多次通知场景,Angular生态常用)
修改Service.ts代码
import { Subject } from 'rxjs'; // 引入RxJS Subject // 定义结果通知流 publishResult$ = new Subject<any>(); callbackResponse; publishStream(publishCapabilities, mediaConstraints) { this.session = session; const videoElement = document.getElementsByTagName('video')[0]; const publishOptions = { publishToken: publishing, mediaConstraints: mediaConstraints, videoElement: videoElement }; this.sdk.publishToChannel(publishOptions, this.publisherCallback.bind(this)); } publisherCallback(error, response) { if (error) { this.logger.log(error); this.publishResult$.error(error); // 通知错误 return; } this.callbackResponse = response; this.publishResult$.next(response); // 推送结果给所有订阅的组件 }
组件侧订阅结果即可:
import { Subscription } from 'rxjs'; private publishSub: Subscription; publishSession() { // 先订阅结果通知 this.publishSub = this.myService.publishResult$.subscribe({ next: (res) => { console.log('拿到发布结果', res); // 处理业务逻辑 }, error: (err) => { console.error('发布失败', err); } }) // 调用发布方法 this.myService.publishStream(); } // 组件销毁时取消订阅,避免内存泄漏 ngOnDestroy() { this.publishSub?.unsubscribe(); }
内容的提问来源于stack exchange,提问作者Feroze Ahmed
相关产品推荐
相关产品推荐

