gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 17:46:22 28 4
gpt4 key购买 nike

我在尝试在我的 Angular 2/4 项目中按顺序运行函数时遇到问题。

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

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

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

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

displayData() 函数在retrieveData() 之前运行,主要是因为retrieveData() 函数中的数据服务。因此图形无法正常显示。

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

我不想使用 Promises 和 Observables,因为它们需要初始函数具有某种返回值才能传递给下一个函数。我在某种程度上设法使用 setTimeOut() 函数实现了它,但我真的怀疑该方法的可靠性和稳健性。

那么,对于在 Angular 2/4 中使用 async 有什么帮助,或者有什么方法可以让函数在没有任何类型的返回 promise 的情况下等待吗?

更新

对于给大家带来的困惑和不便,我们深表歉意。我正在发帖并要求提供一个过于简化的版本。这是我的代码中更完整的部分。我是 Angular 和 Typescript 菜鸟,在异步编程技术方面更是菜鸟。

下面是我在 retrieveAllData() 方法中实现的 promise 。它不会在编译时或运行时给出任何错误。但是当函数仍然异步运行时,即 refreshAllCharts() 仍然在 retrieveAllData() 之前运行。我的 promise 执行有没有漏洞?

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)考虑使用这样的 promise :

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 作为强大的链接结构来序列化异步操作

关于angular - 如何在 Angular 2/4 Typescript 中顺序运行函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45533615/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com