Promise chaining in BrightFutures using flatMap
sonnykr opened this issue · 3 comments
I am trying to do something like this:
function1().flatMap { [weak self] resultOfFunction1 in
self?.function2(resultOfFunction1)
}.onSuccess { resultOfFunction2 in
doSomethingUseful(with: resultOfFunction2)
}
Since the self reference in flatMap for function1 is captured weak (weak self), the compiler throws me error. Usually I do
guard let strongSelf = self else { return nil }
but in this case, the return expects another future. How can this be solved? Seems like a bug (in either the library or it's missing documentation?)
It's a good idea to capture self weakly in the closure passed to flatMap
, since it's executed asynchronously and it would extend the lifetime of self.
To solve your problem, you'll need to cover the case when self is gone inside your closure, so think about what the fallback is, if that is the case. (If you know for sure self cannot be released, you can consider using unowned
instead of weak
.) The way I would solve it is by returning a failed future when self
is nil, so for example:
function1().flatMap { [weak self] resultOfFunction1 in
self?.function2(resultOfFunction1) ?? Future(error: .illegalState)
}.onSuccess { resultOfFunction2 in
doSomethingUseful(with: resultOfFunction2)
}
Hope this helps!
Yes returning another future with error state makes sense in this case. However, after doing something like this, I get Ambiguous use of 'flatMap'
error
// This throws: Ambiguous use of 'flatMap' on line1
function1().flatMap { [weak self] resultOfFunction1 in
guard let strongSelf = self else { return Future(error: .illegalState) }
return strongSelf.function2(resultOfFunction1)
}.onSuccess { resultOfFunction2 in
doSomethingUseful(with: resultOfFunction2)
}.onFailure { (error) in
thatsNotGood(error)
}
same here:
// This throws: Ambiguous use of 'flatMap' on line1
function1().flatMap { [weak self] resultOfFunction1 in
self?.doSomePrepworkForFunction2()
return self?.function2(resultOfFunction1) ?? Future(error: .illegalState)
}.onSuccess { resultOfFunction2 in
doSomethingUseful(with: resultOfFunction2)
}.onFailure { (error) in
thatsNotGood(error)
}
but, this works:
function1().flatMap { [weak self] resultOfFunction1 in
self?.function2(resultOfFunction1) ?? Future(error: .illegalState)
}.onSuccess { resultOfFunction2 in
doSomethingUseful(with: resultOfFunction2)
}.onFailure { (error) in
thatsNotGood(error)
}
Any idea what's going on here?
It's due to the Swift design doing type inference for multi-statement closures. type annotations, like -> Future<V,E>
, can solve it for multi-statement.
c.f. https://bugs.swift.org/browse/SR-6042