【问题标题】:Angular 10 - Chained Promises on Array Don't Calculate All PropertiesAngular 10 - 数组上的链式承诺不计算所有属性
【发布时间】:2020-11-18 02:54:35
【问题描述】:

我是 Angular 和 TypeScript 的新手,遇到了一个问题: 我有一个 LabObject 模型类型的对象数组:我的 LabObject 模型有很多属性,以及两个计算出来的私有属性(private _labTest: number 和 private _vitalSign: number)。

我创建了一个 LabObject 类型的数组并使用 for 循环填充它。自然,我注意到这两个计算在循环仍在运行时并没有完成,因为它们很重,所以我想我会使用一个 Promise。 我想如果我在第一个 Promise 中运行循环,然后在此之后链接两个 Promise,每个计算一个 Promise,它会强制我的计算在我对该数组执行任何其他操作之前完成运行。

似乎我错了,因为并非所有数组元素都以计算出的 _labTest 和 _vitalSign 结束,并且在某些元素中,缺少其中一个或两个。

这是我的方法:

createFile() {

    let getLabObject = new Promise((resolve, reject) => {
      let lab_objects: LabObject[] = [];
      for (let i = 0; i < 10; i++) {
        let lo = this.createLabObject();
        lab_objects.push(lo);
      }
      resolve(lab_objects);
    });

    let getLabTest = objects => {
      return new Promise((resolve, reject) => {
        objects.forEach(item => {
          item.CalculateLabTest();
        });
        resolve(objects);
      });
    };

    let getVitalSign = objects => {
      return new Promise((resolve, reject) => {
        objects.forEach(item => {
          item.CalculateVitalSign();
        });
        resolve(objects);
      });
    };

    let backend = objects => {
      this.http.post('my backend url address', JSON.stringify(objects))
        .subscribe(responseData => {
          console.log(responseData);
        });
    }

    getLabObject.then(objects => {
      return getLabTest(objects);
    }).then(objects => {
      return getVitalSign(objects);
    }).then(objects => {
      return backend(objects);
    });

  }

我得到一个看起来像这样的 JSON 对象:

[{id: 1, name: 'name1'},
{id: 2, name: 'name2', _labTest: 10},
{id: 3, name: 'name3', _vitalSign: 17},
{id: 4, name: 'name4', _labTest: 8, _vitalSign: 6}]

但我希望为每个元素计算 _labTest 和 _vitalSign。 我做错了什么?

【问题讨论】:

  • 计算也是异步的..?此外,http(如果 Angular http)不是一个承诺,而是一个可观察的。我认为你根本不需要为承诺而烦恼..
  • @MikeOne,每个计算都非常简单:我的模型的某些属性的总和或我的模型中的方法总和。我首先想到使用 Promise 的唯一原因是因为我看到我没有获得所有元素的所有属性。你能想到别的办法吗?
  • 如果这些函数不是异步的,你可以按顺序调用它们,然后调用 http observable 并订阅它..
  • 我需要查看 createLabObject 以了解它的作用。后端至少是异步的.. 但没关系,这似乎是你的最后一个动作..
  • @MikeOne,非常感谢您的帮助。我最终在代码的其他地方发现了我的错误——我将不正确的数据类型传递给了我的 LabObject 构造函数,它在其他地方弄得一团糟。但是,您刚刚教会了我关于 Promise 用于异步方法的宝贵一课,我真的很感激。

标签: arrays angular typescript promise angular10


【解决方案1】:

我认为您不需要为此做出承诺。实际上异步代码可能是导致对象不完整的原因。

您正在寻找的是getter function。这使您可以访问一个计算值的方法,就好像它是一个属性一样。因此,它始终是正确且易于访问的。添加一个函数以从您的 LabObject 中提取一个对象,然后您就可以将其提交到您的后端了。

检查这个StackBlitz

app.component.ts:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  labtest: LabObject[] = [];
  ngOnInit() {
    this.labtest.push( new LabObject( 2, 8 ) );
    this.labtest.push( new LabObject( 2, 5 ) );
    this.labtest.push( new LabObject( 34, 1 ) );
    this.labtest.push( new LabObject( 10, 1 ) );
  }
  log() {
    const json = this.labtest.map( labtest => labtest.as_object() );
    console.log( JSON.stringify(json) );
    // instead of logging you want to submit the JSON to your backend to do whatever you wanted to do...
  }
}

class LabObject {
  constructor( 
    public type_a_test: number, 
    public type_b_test: number 
  ) {}

  private get _labTests(): number {
    return this.type_a_test + this.type_b_test;
  }
  private get _vitalSign(): number {
    return 2;
  }
  public as_object(): object {
    return {
      labtests: this._labTests, 
      vitalsigns: this._vitalSign
    }
  }
}

【讨论】:

  • 谢谢,@Rob,我在代码的其他地方发现了我的错误(不正确的数据类型),但您的回答也有助于改进我的代码,让它看起来更专业:)
猜你喜欢
  • 1970-01-01
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多