将 Swift 结合 Future 映射到另一个 Future

Kon*_*Kon 7 swift combine

我有一个返回未来的方法:

func getItem(id: String) -> Future<MediaItem, Error> {
  return Future { promise in
    // alamofire async operation
  }
}
Run Code Online (Sandbox Code Playgroud)

我想在另一种方法中使用它并转换MediaItemNSImage,这是一个同步操作。我希望简单地在原始 Future 上做一个mapor flatMap,但它创建了一个我无法擦除的长 Publisher Future<NSImage, Error>

func getImage(id: String) -> Future<NSImage, Error> {
  return getItem(id).map { mediaItem in
    // some sync operation to convert mediaItem to NSImage
    return convertToNSImage(mediaItem)  // this returns NSImage
  }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Cannot convert return expression of type 'Publishers.Map<Future<MediaItem, Error>, NSImage>' to return type 'Future<NSImage, Error>'

我尝试使用flatMap但有类似的错误。我可以,eraseToAnyPublisher但我认为这隐藏了getImage(id: String返回 Future的事实。

我想我可以getImage在未来包装身体,但这似乎不像链接和映射那么干净。欢迎大家提出意见。

mat*_*att 5

您不能像这样使用Combine 框架中的点点滴滴。你必须建立一个管道\xe2\x80\x94 成为发布者、一些操作员和订阅者(​​您存储这些内容以便管道有机会运行)。

\n\n
 Publisher\n     |\n     V\n Operator\n     |\n     V\n Operator\n     |\n     V\n Subscriber (and store it)\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以在这里,getItem有一个函数可以生成您的发布者,即未来。所以你可以说

\n\n
getItem (...)\n    .map {...}\n    ( maybe other operators )\n    .sink {...} (or .assign(...))\n    .store (...)\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,future(以及整个管道)将异步运行,结果将弹出管道的末尾,您可以用它做一些事情。

\n\n

现在,当然,您可以将“未来”和“地图”放在一起,然后停止出售它们,以便其他人可以将其他操作员和订户附加到它们。您现在已经组装了管道的开始部分,仅此而已。但它的类型不会是 Future;而是 这将是一个AnyPublisher<NSImage,Error>. 这并没有什么问题!

\n

  • 对于 Future,我想向用户传达该函数将仅返回单个值并且完整。 (2认同)