首页 > 解决方案 > 如何从 Observable 返回一个数组

问题描述

嗨,我有一个应该返回数组的函数,在下面的函数中, this.cordovaFile.readAsArrayBuffer(this.cordovaFile.dataDirectory, storageId)实际上返回一个 Promise 数组,我将它转换为 Observable 并存储到timesheetArray变量中,现在 timesheetArray它将返回 Observable 数组,但我只想返回一个数组。下面是代码

请帮忙,如果它只返回一个数组,我不需要在任何地方更改它,因为这个函数在整个应用程序中都使用

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 ??
  });
}

以及为什么我想返回一个数组但不可观察的一个例子

let matchedTimesheet = _.find<TimesheetModel>(this.getAllTimesheets() ,
(timesheet) => travelToDate 
&& timesheet.startOfWork.isSame(travelToDate.startDate.value, 'days')
            ); ```

here in the above code it is expecting an array but not Observable., I can do it by subscribing here also , but if the function returns an array instead of  observable, then i need to change everywhere

标签: angulartypescriptpromiseobservable

解决方案


我不认为你在考虑这个方向是正确的。readAsArrayBuffer是一个异步调用。因此它返回一个承诺。

你不应该简单地TimesheetModel[]从你的getAllTimesheets()方法中返回一个。

相反,您应该返回一个Observable<TimesheetModel[]>. 但是无论你在哪里调用这个getAllTimesheets()方法,你都必须做一个小的改变。

由于它返回一个Observable<TimesheetModel[]>,因此您必须subscribegetAllTimesheets()所有这些地方都必须这样做。或者您必须使用管道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.
  })

推荐阅读