private processArray(evts: Event[]): Promise<void> {
var auditsvc = this.auditSvc;
var t = this;
if(!evts || evts.length ==0 ) {
return;
}
let objArr: any[] = [];
evts.forEach( function (inpEvt) {
auditsvc.getAuditDetails(inpEvt.id).subscribe((data) => {
for(let i=0; i<data.length; i ){
let outObj = {};
outObj['Driver'] = inpEvt.driver.name;
outObj['Executive'] = inpEvt.executive.exec.name;
outObj['Point of Departure'] = inpEvt.pod;
outObj['Date of Departure'] = UtilService.dateToString(inpEvt.date);
outObj['Arrival Time'] = UtilService.timeToString(inpEvt.arrivalTime);
outObj['Departure Time'] = UtilService.timeToString(inpEvt.departureTime);
outObj['Action Timestamp'] = data[i].actionedOnTimestamp;
outObj['Modified By'] = data[i].modifiedBy;
outObj['Comment'] = data[i].comment;
objArr.push(outObj);
}
}, (err) => {
console.log(err);
}, () => {
});
});
if(objArr.length == 0) {
UtilService.openError(t.modalSvc,'No logs found.');
return;
}else{
t.exportAsXLSX(objArr);
}
}
不執行 for each 回圈,但首先執行下一個函式。我希望回圈首先迭代,然后轉到另一個函式,因為回圈回傳另一個函式所需的一些資料。
由于回圈沒有迭代,objArr 長度為 0,它總是給出“未找到日志”錯誤。
uj5u.com熱心網友回復:
問題在于這auditsvc.getAuditDetails()是一個異步操作,因此evts.forEach只需遍歷evts、注冊訂閱——將它們放在異步佇列中——然后退出。回呼函式直到稍后的subscribe某個時間,在異步操作完成之后,并且在您當前的代碼已經檢查之后才會被呼叫objArr.length。
您需要做的是構建一個管道,在所有異步操作完成并填充后objArr.length檢查該管道。objArr
一種方法是創建一個 Observable 陣列,方法是將每個 Observable 映射inpEvt到evts相應的 Observable 以獲取其審計詳細資訊,如下所示:
const auditDetails$: Observable<any>[] = evts.map(inpEvt => {
return auditsvc.getAuditDetails(inpEvt.id).pipe(
map(data => ({ inpEvt, data })) // <-- need to pass inpEvt also because outObj will need it
);
});
然后,您可以將該 Observables 陣列傳遞給 RxJS forkJoin以觸發它們并在陣列中回傳它們的結果:
forkJoin(auditDetails$).pipe( // <-- auditDetails$ is array of Observables
map((auditDetails: any[]) => { // <-- auditDetails is array of all Observable results, here passed to RxJS map operator
})
)
然后,您可以使用 RxJS映射運算子將審核詳細資訊資料轉換為objArr您需要的資料。
為此,在 RxJSmap投影函式中,您可以使用原生 JavaScript Array#map將審計細節陣列映射到outObjs 陣列,如下所示:
forkJoin(auditDetails$).pipe(
map((auditDetails: any[]) => { // <-- RxJS map operator
return auditDetails.map(({ inpEvt, data }) => { // <-- native JS Array#map
const outObj = {};
for(let i=0; i<data.length; i ){
outObj['Driver'] = inpEvt.driver.name;
// ......
outObj['Comment'] = data[i].comment;
}
return outObj;
});
})
)
最后,訂閱該 Observable 管道,您將獲得所需objArr的完全填充狀態:
forkJoin(auditDetails$).pipe(
map((auditDetails: any[]) => {
// ...
})
).subscribe(objArr => { // <-- final result is asynchronously-populated objArr
if (objArr.length == 0) {
UtilService.openError(t.modalSvc,'No logs found.');
return;
} else {
t.exportAsXLSX(objArr);
}
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/481524.html
