You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Chaining optional JSON GET requests efficiently #1155
Hi,
I'm trying to wrap my head around the promise concept and I'm having some issue when dealing with HTTP GET requests.
I have a function f that calls an HTTP endpoint, decodes some JSON and returns a Swift object after doing some transformations on an intermediate type:
rgp in this case is an object containing an array of objects.
return firstly {URLSession.shared.dataTask(.promise,with:urls.Price(forIDs:gamesIDs,country:nation,lang:nation))}.compactMap{tryself.urls.JSONDataDecoder().decode(RawGamePrice.self,from:$0.data)}.compactMap{rgpin
// does some transformations on rgp and then returns
}
Now, I need to bolt several other HTTP calls, which should be executed for a subset of rgp components:
varproms=[Promise<[EuropeGamePrice]>]()for(chunk)inidChunks{proms.append(self.prices(list:chunk,nation:"IT"))}when(resolved:proms).done{resultsinreturnproms.forEach{ddindd.value?.forEach{newPriceing.updateDiscountPrice(gameWith:newPrice.gameID,newPrice:newPrice.salePrice)}}}.catch{errorindebugPrint("cannot fetch prices, using APIs ones",error)}.finally{debugPrint("finished pulling prices")}
As far as I understand, compactMap does not permit chaining other promises with then because it doesn't return a Promise itself.
What's the best way to tackle this situation?
I do not know the subset of object to work with before the second compactMap ends.
I tried embedding the when logic in the latter compactMap but since it's all async the wrapping closure returns before the when ends, and to be honest it doesn't look good enough.
As far as I understand, compactMap does not permit chaining other promises with then because it doesn't return a Promise itself.
Sure it does. All that map and compactMap do is convert Promise<InputType> to Promise<OutputType>. You can continue to extend the chain however you wish.
I suspect you are confusing the types created as the chain is set up with the types that propagate through the chain itself.
The closure is just an argument to map, and map runs as the promise is being set up. But map doesn't run the closure itself; it just saves it to be used later as the chain executes. map itself returns a Promise<String> (in this case).
then makes this conceptually confusing because both the closure and the then return Promise<X>. But the Promise<X> returned by then is not actually the Promise<X> created by the closure (which hasn't even run yet). It's just a wrapper that will run the closure at the appropriate time and then pass the result of the newly-generated promise on to its own descendants.
Activity
GarthSnyder commentedon Jun 22, 2020
Sure it does. All that
mapandcompactMapdo is convertPromise<InputType>toPromise<OutputType>. You can continue to extend the chain however you wish.I suspect you are confusing the types created as the chain is set up with the types that propagate through the chain itself.
is the same as
The closure is just an argument to
map, andmapruns as the promise is being set up. Butmapdoesn't run the closure itself; it just saves it to be used later as the chain executes.mapitself returns aPromise<String>(in this case).thenmakes this conceptually confusing because both the closure and thethenreturnPromise<X>. But thePromise<X>returned bythenis not actually thePromise<X>created by the closure (which hasn't even run yet). It's just a wrapper that will run the closure at the appropriate time and then pass the result of the newly-generated promise on to its own descendants.