【问题标题】:How do I convert an array of Promises to a stream (of Observables?)如何将 Promise 数组转换为流(Observables?)
【发布时间】:2018-01-02 05:46:05
【问题描述】:

假设我有一系列承诺,itemsPromises。其中一些会失败,其中一半可能会成功。

如果我尝试得到这样的响应:

const itemsPromises = raw.map(item =>
            axios({
                method:'get',
                url:`https://www.omdbapi.com/?apikey=${apikey}&i=${item.imdbID}`
            })
        )

const itemsResponses = await Promise.all(itemsPromises)

...我将需要等待很长时间,直到失败的承诺最终超时。我可能会收到 5-6 次成功的回复,但在所有的承诺都被解决或拒绝之前,我无法访问它们。

我能否将这个 Promise 数组转换为某种可迭代形式的 Observable,这样每次我得到一个成功的响应时,我就可以将它传递给我的应用程序并使用它?

【问题讨论】:

  • 你想如何处理被拒绝的承诺?它们应该如何在流中表示?您预期的唯一错误是超时错误吗?
  • 我不介意失去它们。我不知道他们的 API 是如何工作的——有时我会收到错误,抱怨我没有使用“正确”的标头,大多数时候我根本没有收到任何错误,只是从不解决或拒绝 Promise。通常我的请求中至少有一半会通过正确的数据及时得到解决(我可以看到使用 Chrome 开发工具),另一个则陷入困境,但我不介意 2-3 秒后他们会发生什么,只要我至少得到了几个成功的回复。

标签: promise rxjs


【解决方案1】:

Merge 运算符让您同时执行每个 http 调用

Rx.Observable.merge(null,
raw.map(item =>
    Rx.Observable.fromPromise(axios({
        method: 'get',
        url: `https://www.omdbapi.com/?apikey=b54e8554&i=${item.imdbID}`
    })).catch(err=>Rx.Observable.of({err,item}))
)).subscribe()

【讨论】:

  • 您可以省略this,因为Rx.Observable.merge 是静态的并且不使用上下文。你可以通过nullundefined。此外,Rx.Observable.merge 应该接受单个数组参数。或者你可以使用数组展开语法。
  • 我会编辑它。我尝试将数组作为参数,但它不起作用。
  • 是的,你是对的。没有采用数组参数的重载,因此数组扩展语法将是唯一的其他选择。
  • 您可能需要调整您的答案以吞下(或记录)每个承诺的错误 - 如OP's comment 中所述。
  • 也很确定你不需要fromPromise,合并将为你做from
猜你喜欢
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 2021-05-28
  • 2022-01-07
  • 1970-01-01
  • 2014-05-29
相关资源
最近更新 更多