【问题标题】:how to properly assign fields in subscribe?如何正确分配订阅中的字段?
【发布时间】:2021-06-10 00:35:01
【问题描述】:

我正在用 Angular 编写一个项目,但在我看来,我的问题与此无关。 我按顺序发送请求并尝试将响应值分配给双数组private labels: any [][] = [[]];

getInfo(url: string, command: string, accessToken: string, companyToken: string, size: number) {
    return this.httpClient.post(url,
        JSON.stringify({
            'cmd': 'getInfo',
            'command': command,
            'date': this.getDate(),
            'accessToken': accessToken,
            'companyToken': companyToken,
            'size': size
        })
    );
}

  getData() {
    for (let i = 0; i < this.commands.length; i++) {
        let labelsArr: string[] = [];
        let dataArr: string[] = [];
        this.getInfo(this.url, this.commands[i], this.accessToken, this.companyToken, 12)
            .subscribe(
                response => {
                    for (let j = 0; j < Object.keys(response).length; j++) {
                            labelsArr[j] = Object.entries(response)[j][1][0];
                            dataArr[j] = Object.entries(response)[j][1][1];
                    }
                    this.labels[i] = labelsArr;
                    //not empty
                    console.log(this.labels);

                    this.AllData[i] = dataArr;
                });
    }
    //empty
    console.log(this.labels);

}

在getData()中我输出了结果数组,事实是输出到subscribe时不为空,但是如果我尝试在subscribe之外显示字段的值,原来是数组是空的,我不明白这与什么有关,有人可以建议吗?

附言

我认为这是因为响应来晚了我有时间使用标签,我怎样才能使它们同步?

【问题讨论】:

    标签: javascript angular typescript web


    【解决方案1】:

    订阅回调中的代码在getData()中的console.log(this.labels)之后异步执行。如果您需要在所有getInfo() 请求之后使用this.labels,则需要异步执行。使用 forkJoin 加入所有 getInfo() Observables:

        getData() {
          const observables = [];
          for (let i = 0; i < this.commands.length; i++) {
              observables.push(this.getInfo(this.url, this.commands[i], this.accessToken, this.companyToken, 12));
          }
          forkJoin(observables).subscribe(responses => {
            for(response of responses) {
              let labelsArr: string[] = [];
              let dataArr: string[] = [];
              for (let j = 0; j < Object.keys(response).length; j++) {
                labelsArr[j] = Object.entries(response)[j][1][0];
                dataArr[j] = Object.entries(response)[j][1][1];
              }
              this.labels[i] = labelsArr;
              this.AllData[i] = dataArr;
            }
          });
        }
    

    还有其他选择,例如将每个可观察对象映射到其自己的管道中,然后将它们连接起来。此外,getInfo() 应该返回一个类型化的对象,因此您不需要使用 Object.keys

    【讨论】:

    • 我认为这是因为响应来晚了我有时间使用标签,我怎样才能使它们同步?
    【解决方案2】:

    好的,成功了

    async getData() {
    
        for (let i = 0; i < this.commands.length; i++) {
            let labelsArr: string[] = [];
            let dataArr: string[] = [];
            await this.getInfo(this.url, this.commands[i], this.accessToken, this.companyToken, 12)
                .toPromise().then(
                    response => {
                        for (let j = 0; j < Object.keys(response).length; j++) {
                                labelsArr[j] = Object.entries(response)[j][1][0];
                                dataArr[j] = Object.entries(response)[j][1][1];
                        }
                        this.labels[i] = labelsArr;
                        this.AllData[i] = dataArr;
                    });
        }
        //
       console.log(this.labels);
    
    }
    

    【讨论】:

    • 此解决方案将按顺序发送请求。您可以使用 Promise.all() 将它们并行发送并在所有完成后继续。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    • 2017-02-12
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多