【问题标题】:Implement for-await-of statement in RxJS在 RxJS 中实现 for-await-of 语句
【发布时间】:2020-02-22 10:32:32
【问题描述】:

我有如下声明:

 for await (const blob of client.list()) {
    console.log('\t', blob.name);
}

client.list() 返回一个异步可迭代迭代器,并期望使用for await...of 来解决承诺。我想将代码合并到实例化客户端的现有 rxjs 管道中。

我到处寻找,如果不解决管道内的承诺而不是转换成可观察对象,我不知道该怎么做。

任何帮助将不胜感激!

【问题讨论】:

  • "...期望使用for await...of 来解决承诺..."消费承诺,而不是解决他们。它们由其他代码解决,而不是上面的循环。
  • 我认为这正是您想要做的github.com/kgurkan/rxjs-async-iterator。也讨论 RxJS github github.com/ReactiveX/rxjs/issues/4002
  • @martin 是的,我见过那个,它是我需要做的相反的事情。从 RxJS 进入 for-await-of。
  • @T.J.Crowder 从循环中可以看出,我可以从 Promise 中获取信息;那是'blob'及其属性'name'。因此我认为它确实解决了这个承诺。
  • @MichaelMay - 恐怕这根本不是承诺的工作方式。 :-) 如果您获得了一个 Promise 实例,那么您就没有可以用它来解决或拒绝它。同样,上面的所有代码都是使用这个promise——也就是说,代码responds这个promise被解决或拒绝(被其他代码)。这只是一个术语。 解决一个承诺是履行它或使其履行/拒绝依赖于另一个承诺的行为。

标签: javascript angular asynchronous rxjs reactivex


【解决方案1】:

我找不到现有的 rxjs 运算符,但自己制作似乎并不难。在将其他 API 与 observable 集成时,您可以在传递给 observable 构造函数的函数中与 API 进行交互。这在触发下一个/错误/完成时提供了很大的灵活性。

编辑 - 我为此添加了第二个选项,使用 rxjs 运算符并避免显式调用 next/error/complete。

const {
  Observable,
  operators,
  from
} = rxjs;
const {take, takeWhile, expand, map, filter} = operators;

const asyncGen = async function*(x = -1) {
  while(x++ < 5) {
    yield x;
  }
};

const fromAsyncIter = iterable => new Observable(subscriber => {
  let unsubscribed = false;
  const iterate = async () => {
    try {
      for await (let n of iterable) {
        console.log('await', n);
        subscriber.next(n);
        if (unsubscribed) return;
      }
      subscriber.complete();
    } catch (e) {
      subscriber.error(e);
    }
  }
  iterate();
  return () => unsubscribed = true;
});

const fromAsyncIter2 = iterable =>
  from(iterable.next()).pipe(
    expand(() => iterable.next()),
    takeWhile(x => !x.done),
    map(x => x.value)
  );

// const source = fromAsyncIter(asyncGen()).pipe(take(2));
const source = fromAsyncIter2(asyncGen()).pipe(take(2));

source.subscribe({
  next: x => console.log('next', x),
  error: e => console.error(e),
  complete: () => console.log('complete')
});
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.js"&gt;&lt;/script&gt;

【讨论】:

  • 我觉得asyncIterable可以简化为:const asyncIterable = { async *[Symbol.asyncIterator](x = -1) { while(x++ &lt; 5) yield x } }
  • 也许这是与 rxjs 集成的唯一方法,但这不是我的想法。不涉及 async 有没有办法做到这一点?
  • @MichaelMay 所以你想调用 .then/.catch 而不是使用 async/await 吗?请问为什么?
  • @NickL 你的第二个 sn-p 正是我所追求的,它就像一个魅力!我一直在寻找使用“from”、“of”和运算符来隐藏处理 promise 的复杂性,无论是 then/catch 还是 await。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 2015-05-30
  • 2014-05-19
  • 1970-01-01
相关资源
最近更新 更多