2

Redux-Observable 依赖于 RxJS。

我需要使用 RxJS-DOM 中的 filereader 函数。

https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/doc/operators/filereader.md

看起来 RxJS-DOM 包含与 RxJS 相同的基本 API 集(加上 DOM 的)。

是否可以要求 Redux-Observable 使用 RxJS-DOM 而不是 RxJS?导入两者都会使我的构建体积膨胀。

4

1 回答 1

3

RxJS-DOM 又名rx-dom适用于 RxJS v4,而不适用于 v5+。两者格格不入。情况确实令人困惑。

在 v5+ 中没有官方等价物fromReader,这里是问题单跟踪:https ://github.com/ReactiveX/rxjs/issues/1223

尽管可能不是您想听到的,但只要您了解 Observables 的基本工作原理,围绕其他 API 创建自定义 Observable 包装器应该相当简单。无论如何,这是一项非常有价值的学习技能。

fromReader实际上是用词不当,因为您没有为它提供 FileReader,而是为它提供了 aFile并且它在内部创建了自己的FileReader来排空它。所以让我们说吧fromFile。这是一个非常基本的起点示例:

class FromFileAsTextObservable extends Observable {
  constructor(file, encoding) {
    super();

    this.file = file;
    this.encoding = encoding;
  }

  _subscribe(subscriber) {
    const reader = new FileReader();

    const loadHandler = event => {
      subscriber.next(event.target.result);
      subscriber.complete();
    };

    const errorHandler = event => {
      subscriber.error(event.target.error);
    };

    reader.addEventListener('load', loadHandler, false);
    reader.addEventListener('error', errorHandler, false);

    reader.readAsText(this.file, this.encoding);

    return () => {
      reader.removeEventListener('load', loadHandler, false);
      reader.removeEventListener('error', errorHandler, false);
    };
  }
}

class FromFileFactory {
  constructor(file) {
    this.file = file;
  }

  asText(encoding) {
    return new FromFileAsTextObservable(this.file, encoding);
  }
}

const fromFile = file =>
  new FromFileFactory(file);

const file = new File(['hello world'], 'example.txt', {
  type: 'text/plain',
});

fromFile(file).asText()
  .subscribe(text => console.log(text));

虽然对于复杂的 API 等来说这是更灵活的方式,但如果您只想读取文件并处理加载/错误,您可以改为创建一个匿名的 Observable,如下所示:

const fromFileAsText = (file, encoding) => new Observable(subscriber => {
  const reader = new FileReader();

  const loadHandler = event => {
    subscriber.next(event.target.result);
    subscriber.complete();
  };

  const errorHandler = event => {
    subscriber.error(event.target.error);
  };

  reader.addEventListener('load', loadHandler, false);
  reader.addEventListener('error', errorHandler, false);

  reader.readAsText(file, encoding);

  return () => {
    reader.removeEventListener('load', loadHandler, false);
    reader.removeEventListener('error', errorHandler, false);
  };
});

const file = new File(['hello world'], 'example.txt', {
  type: 'text/plain',
});

fromFileAsText(file)
  .subscribe(text => console.log(text));
于 2017-07-10T22:11:59.100 回答