如何使用observables和/或异步生成器递归访问promises?

时间:2018-06-17 16:52:37

标签: typescript asynchronous async-await rxjs observable

我一直在尝试使用异步迭代器和可观察对象来扩展一个承诺树

上下文

我正在使用typescript 2.9并使用ts-node

运行程序

假设我有一个函数fetchData(params)以这种方式返回一个承诺

async fetchData(params) {
  const fetchedData = wait fetch(...params);
  return {
    nextParams: fetchedData.nextParams,
    nodeData: fetchedData.nodeData
  }
}

目标

我想要做的是创建一个可以订阅读取每个节点的observable,每个节点都包含nodeData。所以这留下了一个使用fetch

的递归函数

变通方法 可以递归地返回{ nodeData: ...}{ nodeData: ..., nextParams: ... }的函数,以便消费者可以调用等待下一个

async transversePromiseTree(fetchParams) {
  const { nextParams, nodeData } = await fetchData(fetchParams);
  if (nextParams) {
    return {
      nodeData,
      next: transversePromiseTree(nextParams)
    }
  }

  return { nodeData };
}

async function getData(rootFetchParams) {
  let node = await transversePromiseTree(rootFetchParams);
  while (node.next) {
    console.log(node.nodeData);
    node = await node.next
  }
}

直到它完美无缺,输出如下:

... node data ...
*after couple of seconds*
... another node data ...
*after couple of seconds*
... some other nothe data ...
*until it reaches the end of the tree*

约束该程序不知道列表或树有多大

问题当我想以这种方式创建异步迭代时出现问题,我想创建这个可迭代的,以便将其转换为可观察的

async *transversePromiseTree(fetchParams) {
  const { nextParams, nodeData } = await fetchData(fetchParams);
  yield nodeData;
  yield * transversePromiseTree(nextParams);
}

迭代的消费者看起来像这样:

async function getData(rootFetchParams) {
  const nodeTree = await transversePromiseTree(rootFetchParams);
  for await(let nodeData of nodeTree) {
    console.log(nodeData)
  }
}

当我运行程序时,我希望输出完全相同,但我得到了

TypeError: Symbol.asyncIterator is not defined.

我试图找到的解决方案

所有这一切的主要原因只是消费者对Observable的抽象,现在我的问题是:

  • 有没有办法在没有异步迭代的情况下使用此行为创建一个observable?
  • 是否有任何解决方案对Symbol.asyncIterator未定义错误,因此异步迭代实际上是可用的?

我一直在查看文档,异步生成器似乎仍在讨论中

任何帮助都非常感谢!谢谢!

1 个答案:

答案 0 :(得分:0)

问题在于Symbol.asyncIterator没有在NodeJS上下文中定义。因此,您需要为NodeJS定义此填充程序:

(Symbol as any).asyncIterator = Symbol.asyncIterator || Symbol.for("Symbol.asyncIterator");