Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/450.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJs Observable由Iterable创建,承诺每次迭代不更新值_Javascript_Promise_Rxjs_Iterator_Reactive Programming - Fatal编程技术网

Javascript RxJs Observable由Iterable创建,承诺每次迭代不更新值

Javascript RxJs Observable由Iterable创建,承诺每次迭代不更新值,javascript,promise,rxjs,iterator,reactive-programming,Javascript,Promise,Rxjs,Iterator,Reactive Programming,我想创建一个可以从iterable中观察到的RxJS,如下所示: const networkIterableFactory = (resource: string) => { let i = 0; return { [Symbol.iterator]() { return { next() { return { done: false, value: fetch(resource

我想创建一个可以从iterable中观察到的RxJS,如下所示:

const networkIterableFactory = (resource: string) => {
  let i = 0;
  return {
    [Symbol.iterator]() {
      return {
        next() {
          return {
            done: false,
            value: fetch(resource, {
              mode: 'cors',
            }).then(async response => {
              console.log('i = ', i);
              await throttle(10000); // Do some stuff
              i++;
              return {i: 'i'};
            }),
          };
        },
      };
    },
  };
};

function throttle(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

let networkIterable = networkIterableFactory('google.com');

let network$ = rxjs.from(networkIterable).pipe(rxjs.operators.take(5));

network$.subscribe(() => console.log('yo!'));

问题是我打印的是0的5倍。iterable的迭代器保存其状态的方式似乎是通过更新外部闭包。from只将整个iterable作为一个emmission,因此返回一组未解析的承诺,但我需要通过承诺回调中的逻辑更改迭代器状态。在从迭代器发出下一项之前,有没有一种方法可以让可观察对象等待承诺解决?我宁愿避免使用asyncIterable,因为我不想引入IxRx。

由于iterable的值是异步返回的,那么您应该实现
Symbol。asyncIterator
而不是
Symbol。迭代器
尝试以下方法:

const networkIterableFactory = (resource: string) => {
  let i = 0;
  return {
    [Symbol.asyncIterator]() {
      return {
        next() {
          return fetch(resource, { mode: 'cors' }).then(x => ({ done: false, value: x }));
        },
      };
    },
  };
};

function throttle(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

let networkIterable = networkIterableFactory('google.com');

let network$ = rxjs.from(networkIterable).pipe(rxjs.operators.take(5));

network$.subscribe(() => console.log('yo!'));
编辑:

RxJS实际上还不支持异步迭代器:

我还尝试了一个
异步生成器

const { from } = require('rxjs');

async function* test() {};
const asyncGenerator = test();
from(asyncGenerator);
但它抛出:

TypeError:您提供了一个无效的对象,其中应该有一个流。 您可以提供一个可观察的、承诺的、数组的或可观察的


因此,您将无法使用此模式,我实际上认为RxJS不适合像您使用
take
那样“拉取”数据(如果此模式起作用,它将以无限请求循环结束,即使您仅使用
take
5个结果)。它的设计目的是将内容“推送”给任何侦听者。

是的,这是我的第一个想法,不幸的是rxjs.from不支持异步迭代器。是的,我认为他们将此功能放在IxRx库中,不幸的是,我无法使用。无论如何,我只是想确认这是一条死胡同,谢谢你的帮助。