Есть ли способ выполнить побочный эффект в будущей цепочке, не меняя распространение значения - PullRequest
0 голосов
/ 02 апреля 2019

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

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

Я ищу что-то вроде:

.getResource() //returns future
   .flatMap(resource => resource.getUsageResult()) //returns future
    .FUNCTION_I_NEED(resource.free()) 
    //executes for failures and successes, doesn't change propagated exceptions or values
   .flatMap(usageResult => mutate(usageResult)) //returns future

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Вы можете сделать что-то вроде этого:

getResource()
  .flatMap(resource => {
    resource.getUsageResult()
      .map(result => {
        // .map makes sure the usage result is done
        // do your side effect here
        yourSideEffectOn(resource)
        // return the result again so you can do something with it
        result
      })
  })
  .flatMap(usageResult => mutate(usageResult))

Вы должны быть в состоянии упростить это, используя для понимания:

for {
  resource <- getResource()
  usageResult <- getUsageResult(resource)
} yield {
  yourSideEffectOn(resource) // will not wait if it returns a future
  mutate(usageResult)
}

Если я правильно помню, это должно работатьа также:

for {
  resource <- getResource()
  usageResult <- getUsageResult(resource)
  _ = yourSideEffectOn(resource) // will not wait if it returns a future
} yield mutate(usageResult)

Если вы хотите дождаться окончания побочного эффекта (и прервать его, если он не получится), вы можете также использовать flatMap побочного эффекта:

for {
  resource <- getResource()
  usageResult <- getUsageResult(resource)
  _ <- yourSideEffectOn(resource) // will wait for side effect to finish
} yield mutate(usageResult)
1 голос
/ 02 апреля 2019

Возможно, вы ищете andThen -оператор:

something.getResource()
.flatMap(resource => resource.getUsageResult() andThen { case _ => resource.free() })
.flatMap(usageResult => mutate(usageResult))
...