嗨,我有一个应返回Array的函数,在下面的函数中,this.cordovaFile.readAsArrayBuffer(this.cordovaFile.dataDirectory, storageId)
实际上返回了一个Promise Array,我将其转换为Observable并将其存储到timesheetArray
变量中,现在将{{1}它将返回Observable数组,但我只想返回一个Array。下面是代码
请帮助,如果它只返回一个数组,则我不需要在任何地方更改它,因为此功能在整个应用程序中都使用
timesheetArray
还有一个示例,为什么我要返回一个数组但不可观察
public getAllTimesheets(): TimesheetModel[] {
const storageId = TIMESHEET_KEYS.ALL_TIMESHEET;
const timesheetArray = from(
this.cordovaFile
.readAsArrayBuffer(this.cordovaFile.dataDirectory, storageId)
.then((compressedTimesheet) => {
const start = moment();
const uint8array = new Uint8Array(compressedTimesheet);
const jsonTimeSheet = this.LZString.decompressFromUint8Array(uint8array);
this.log.debug(`LocalStorageMaterialService: getMaterials() from files: Decompression took ${moment().subtract(start.valueOf()).valueOf()} ms`);
return <TimesheetModel[] > JSON.parse(jsonTimeSheet) || [];
})
.catch((error) => {
this.log.debug('LocalStorageMaterialService: Retrieving materials from file storage was not possible: ', JSON.stringify(error));
return [];
})
)
timesheetArray.subscribe((timesheet) => {
// here how to return an Array ??
});
}
答案 0 :(得分:2)
我认为您没有考虑正确的方向。 readAsArrayBuffer
是一个异步调用。因此,它返回了一个承诺。
您不应该简单地从TimesheetModel[]
方法返回一个getAllTimesheets()
。
相反,您应该返回一个Observable<TimesheetModel[]>
。但是无论您在何处调用此getAllTimesheets()
方法,都必须进行一些小的更改。
由于它返回了Observable<TimesheetModel[]>
,因此在所有这些地方都必须从subscribe
到getAllTimesheets()
。否则,您必须使用Observable
管道在模板中阅读此async
。
我建议后者。
因此,请对您的getAllTimesheets()
方法进行以下更改。
public getAllTimesheets(): Observable<TimesheetModel[]> {
const storageId = TIMESHEET_KEYS.ALL_TIMESHEET;
return from(
this.cordovaFile
.readAsArrayBuffer(this.cordovaFile.dataDirectory, storageId)
.then((compressedTimesheet) => {
const start = moment();
const uint8array = new Uint8Array(compressedTimesheet);
const jsonTimeSheet = this.LZString.decompressFromUint8Array(uint8array);
this.log.debug(`LocalStorageMaterialService: getMaterials() from files: Decompression took ${moment().subtract(start.valueOf()).valueOf()} ms`);
return <TimesheetModel[] > JSON.parse(jsonTimeSheet) || [];
})
.catch((error) => {
this.log.debug('LocalStorageMaterialService: Retrieving materials from file storage was not possible: ', JSON.stringify(error));
return [];
})
);
}
然后,无论您在哪里使用它,subscribe
都可以使用它:
// unsubscribe this subscription on ngOnDestroy()
const subscription = getAllTimesheets()
.subscribe(timesheetData => {
// Here you'll get that data.
})
答案 1 :(得分:1)
请勿将您的全部承诺记录为可观察的。设置BehaviorSubject
,并使用.next()
用承诺的结果更新主题。然后,您可以订阅该结果。
假设这一切都在服务中,则可以按以下步骤进行设置:
@Injectable({ providedIn: 'root' })
export class TimesheetsService {
/**
* Create a new behavior subject with an empty array. This is what you will
* subscribe to from outside of your service.
*/
public timesheets$: BehaviorSubject<TimesheetModel[]> = new BehaviorSubject([]);
constructor() {
// Call your service method to GET your data.
this.getAllTimesheets();
}
/**
* This method is how you will update your behavior subject and can be called
* from outside the service each time you want to update your result.
*/
public getAllTimesheets() {
return this.cordovaFile
.readAsArrayBuffer(this.cordovaFile.dataDirectory, storageId)
.then((compressedTimesheet) => {
const uint8array = new Uint8Array(compressedTimesheet);
const jsonTimeSheet = this.LZString.decompressFromUint8Array(uint8array);
// On success, update the behavior subject with the result of your call.
return timesheets$.next(JSON.parse(jsonTimeSheet));
})
// Or on error, update the behavior subject.
.catch(() => timesheets$.next([]));
}
}
然后,您可以在组件中订阅可观察的result$
。
export class YourComponent implements OnInit {
timesheets: TimesheetModel[];
constructor(private timesheetsService: TimesheetsService) {
// Optionally call your service method again to GET fresh data.
this.timesheetsService.getAllTimesheets();
}
ngOnInit() {
/**
* Subscribe to the result of your service call and pass the result to a
* reference to be consumed by your component.
*/
this.timesheetsService.timesheets$
.subscribe((timesheets) => this.timesheets = timesheets);
}
}
答案 2 :(得分:-1)
您可以简单地使用as []
timesheetArray.subscribe((timesheet) => {
const time_sheet = timesheet as [];
});