加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何在Angular 2/4 Typescript中按顺序运行函数

发布时间:2020-12-17 17:23:29 所属栏目:安全 来源:网络整理
导读:我无法在Angular 2/4项目中按顺序运行函数. 我有retrieveData()函数,它从数据服务中检索数据并将它们分配到我声明的数组中. 然后我有displayData()函数,它使用存储在数组中的数据并将它们显示在图表中. 当我尝试运行它们时,例如: function(){ this.retrieve
我无法在Angular 2/4项目中按顺序运行函数.

我有retrieveData()函数,它从数据服务中检索数据并将它们分配到我声明的数组中.

然后我有displayData()函数,它使用存储在数组中的数据并将它们显示在图表中.

当我尝试运行它们时,例如:

function(){
  this.retrieveData();
  this.displayData();
}

displayData()函数首先在retrieveData()之前运行,主要是因为retrieveData()函数中的数据服务.因此无法正确显示图表.

我发现可以按顺序运行函数的方法之一是异步库中的async.waterfall但是我无法将库导入到我的项目中,控制台日志说:
未捕获错误:模块“AppModule”导入的意外值“瀑布”.请添加@NgModule注释.

我不想使用Promises和Observables因为它们需要初始函数来获得某种返回值以传递给下一个函数.我有点设法使用setTimeOut()函数实现它,但我真的怀疑该方法的可靠性和稳健性.

那么,在Angular 2/4中使用async的任何帮助,或任何一种使函数等待而没有任何返回承诺的方法?

UPDATE

很抱歉造成困难和不便.我发帖并要求过度简化的版本.这是我的代码中更完整的部分.我是一个Angular和Typescript noob,在涉及异步编程技术时更多的菜鸟.

下面是我在retrieveAllData()方法中实现的promise.它不会在编译时或运行时给出任何错误.但是当函数仍然异步运行时,即refreshAllCharts()仍然在retrieveAllData()之前运行.我的承诺实施有什么缺陷吗?

import { Component,OnInit,AfterContentInit } from '@angular/core';
import { DataService } from '../data.service';
import {BaseChartDirective} from 'ng2-charts/ng2-charts';
import {IMyDpOptions,IMyDateModel} from 'mydatepicker';

//import {MomentTimezoneModule} from 'angular-moment-timezone';
import * as moment from 'moment-timezone';

// import async from 'async-waterfall';

@Component({
  templateUrl: 'chartjs.component.html'
})
export class ChartJSComponent {

  tempArr = []; //array to store temperature values for the chart
  timeTempArr = []; //array to store timestamps for the chart label

  device = "1CB001"; //a parameter used for the data service method to query the database

  dateSelected; //variable to store the date chosen from the datepicker on the html side of the component

  constructor(private dataService: DataService){
  }

  ngOnInit(){
  }

//function to retrieve temperature values and assign them into "tempArr" array
  retrieveTempDataAssign(){
    var _arr = new Array();

    this.dataService.getData(this.device,this.dateSelected).subscribe(response => {

      console.log("Response: " + JSON.stringify(response));
      for(var item of response){
        _arr.push(item.Temperature);
      }

      this.tempArr = _arr;
      console.log("Array assigned Temp: " + this.tempArr);
    });

    this.retrieveTempTimeDataAssign();

  }

//function to retrieve time values and assign the date and time objects into "timeTempArr" array
  retrieveTempTimeDataAssign(){

    var _arr = new Array();

    this.dataService.getData(this.device,this.dateSelected).subscribe(response => {

      for(var item of response){
        // var value = "'" + item.Date + "'";
        // _arr.push(value);

        var value = item.Date;
        var time = moment.tz(value,"Asia/singapore");
        _arr.push(time);
      }
      this.timeTempArr = _arr;
      console.log("Array assigned Time: " + this.timeTempArr);
    });
  }

//function to refresh the whole of Temperature chart
  refreshTempChart(){
    this.showTempData();
    setTimeout(() => this.showTempLabels(),500);
  }

//function to assign the "tempArr" array into the dataset for the temperature chart
  showTempData(){
    console.log("To display: " + this.tempArr);
    this.datasetsTemp = [{
      label: "Values",data: this.tempArr
    }];
  }

//function to assign the "timeTempArr" array into the labels for the temperature chart
  showTempLabels(){
    console.log("To label: " + this.timeTempArr);
    this.labels = this.timeTempArr;
  }

//date picker format
  private myDatePickerOptions: IMyDpOptions = {
        dateFormat: 'yyyy-mm-dd',};

//change event listener on the datepicker
  onDateChanged(event: IMyDateModel){

    this.dateSelected= event.formatted;
    console.log("Selected Date: " + this.dateSelected);

//**The implementation part**
    this.retrieveAllData().then(()=>{
      this.refreshAllCharts();
    })

  }

//to run all functions to retrieve respective data
  retrieveAllData(){
    return new Promise((resolve,reject) => {
      this.retrieveTempDataAssign(); //assign the retrieved values into the array first

      return true;
    });
  }

//to run all functions to update all the charts
  refreshAllCharts(){
    this.refreshTempChart();
  }

//objects used by the chart to display data
  private datasetsTemp = [
    {
      label: "Values",data: []
    }
  ];

  private labels = [];

  private options = {
    scales: {
      xAxes: [{
          display: true,type: "time",time: {
              unit: "hour",tooltipFormat: 'YYYY-MM-DD hh:mm A'
          },scaleLabel: {
              display: true,labelString: 'Time'
          }
      },],yAxes: [{
        ticks: {
          beginAtZero: false
        }
      }]
    }
  };
}

解决方法

使用promise时,您不必返回任何值以传递给下一个函数.
如果你想保持函数签名不变(即retrieveData()和displayData()不带任何参数并返回void)考虑使用这样的promises:

private dataStorage: string = null;
private retrieveDataResolver;

  displayData(): void {
    // your display code goes here
    console.log("2. DISPLAYING DATA",this.dataStorage);
  }
  retrieveData(): void {
    // your async retrieval data logic goes here
    console.log("1. GETTING DATA FROM SERVER");
    setTimeout(() => { // <--- Change it - your service data retrieval
      this.dataStorage = '++DATA++';
      this.retrieveDataResolver(); // <--- This must be called as soon as the data are ready to be displayed
    },1000);
  }

  retrieveDataPromise(): Promise<any> {
    return new Promise((resolve) => {
      this.retrieveDataResolver = resolve;
      this.retrieveData();
    })
  }
  retrieveAndThenDisplay() {
    this.retrieveDataPromise().then(() => {this.displayData()});
  }

我建议使用promise wrapper作为强大的链接构造来序列化异步操作

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读