【问题标题】:How to wait until subscribe finishes | Angular 9如何等到订阅完成 |角 9
【发布时间】:2021-04-13 09:13:42
【问题描述】:

我的任务是在 contest.service.ts 中创建一个方法,该方法将从服务器获取数据(比赛),对其进行必要的操作并返回结果。

contest.service.ts

    getContests() {
        let id = IDs.contests.getAll;
        let body = { 
            ...
        };

        let result;

        this.wsservice.send(id, body);

        this.wsservice.on<any>(IDs.contests.getAll)
            .subscribe((msg) => {
                console.log('msg', msg);
                if (!msg['code']) {
                    result = msg;
                    console.log('contests msg', result);
                    this.contests = result.map(contest => {
                        return new Contest({
                            id: contest.id,
                            name: contest.name || "Нет названия",
                            description: contest.description,
                            contestTasks: contest.tasks || []
                        });
                    });
                }
                else {
                    result = "Error";
                }
            });

        return result;
    }

我需要等到订阅 this.wsservice.on(IDs.contests.getAll) 完成,然后从中返回结果。 websocket.service.ts 中的方法:

    public send(eventId: any, data: any = {}): void {
        console.log('SEND');
        let that = this;
        if (eventId && this.isConnected && this.websocket$) {
            data['id'] = eventId;
            this.websocket$.next(data);
        } else {
            setTimeout(function() {
                that.send(eventId, data);
            }, 500);
            console.log('Still connecting, resending messsage...');
        }
    }

    public on<T>(eventId: any): Observable<T> {
        console.log(eventId);
        if (eventId) {
            return this.wsMessages$.pipe(
                filter((message: IWsMessage<T>) => message.id === eventId),
                map((message: IWsMessage<T>) => message.result ? message.result : message.error)
            );
        }
    }

【问题讨论】:

  • 这个问题已经回答过好几次了。来自 Promise(和 Observable)的数据是异步的。它不能像您尝试的那样同步返回。请完整阅读this 帖子以了解什么是异步数据以及如何使用它。
  • @MichaelD,您是否将 Angular 中的新手发送到一个有数百页的答案???。
  • @Quid,您的服务应该返回 observables 并且您在组件中订阅。如果你想返回一个对象转换响应并使用pipe(switchMap(res=&gt;{....return of(your object)}
  • @Eliseo:也许我应该更清楚一点。我指的是OP的问题和自我回答。这是我在 SO 中看到的对异步范式的最快和自给自足的解释。

标签: angular observable angular9 subscription


【解决方案1】:

改进我的评论。

你应该返回一个 observable。你可以使用

getContests() {
   ....
   return this.wsservice.on<any>(IDs.contests.getAll).pipe(
    //we don't want the response else
    switchMap(msg)=>{
      ..do something with the msg..
      //create an object
      const contest= new Contest({
                 ...});
       //we need return an observable, we use rxjs operator 'of'
       return of(contest)
   }
   )

或者使用地图

getContests() {
   ....
   return this.wsservice.on<any>(IDs.contests.getAll).pipe(
    //we are going to transform the response
    map(msg)=>{
      ..do something with the msg..
      //create an object
      const contest= new Contest({
                 ...});
       return contest; //<--see that return simple the object
   }
   )

看到返回一个可观察的,所以在你的组件中订阅

this.service.getContests().subscribe(res=>{
   //here you has the object contest
   console.log(res)
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-29
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    相关资源
    最近更新 更多