Картография Swift Combine Future в другое будущее - PullRequest
1 голос
/ 16 марта 2020

У меня есть метод, который возвращает Future:

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

Я хочу использовать его в другом методе и преобразовать MediaItem в NSImage, что является синхронной операцией. Я надеялся просто сделать map или flatMap в исходном Future, но он создает длинный 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
  }
}

Я получаю следующую ошибку:

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

Я пытался использовать flatMap, но с похожей ошибкой. Я могу eraseToAnyPublisher, но я думаю, что это скрывает тот факт, что getImage(id: String возвращает будущее.

Полагаю, я могу обернуть тело getImage в будущем, но это не так чисто, как сцепление и картирование. Любые предложения приветствуются.

1 Ответ

1 голос
/ 16 марта 2020

Вы не можете использовать кусочки, обрывки и осколки из структуры Combine, как это. Вы должны сделать конвейер - издатель, некоторые операторы и подписчик (который вы храните, чтобы конвейер имел возможность работать).

 Publisher
     |
     V
 Operator
     |
     V
 Operator
     |
     V
 Subscriber (and store it)

Итак, здесь getItem - это функция, которая создает ваше Издательство, Будущее. Таким образом, вы можете сказать

getItem (...)
    .map {...}
    ( maybe other operators )
    .sink {...} (or .assign(...))
    .store (...)

Теперь будущее (и весь конвейер) будет работать асинхронно, а результат появится в конце конвейера, и вы можете что-то с ним сделать.

Теперь, конечно, вы можете соединить Будущее и Карту вместе, а затем stop, , торгуя ими, чтобы кто-то else мог присоединить к ним других операторов и абонента. Теперь вы собрали начало конвейера и не более. Но тогда его тип не будет будущим; это будет AnyPublisher<NSImage,Error>. И в этом нет ничего плохого!

...