Await in Swift, no Promises broken :)

Mladen Despotovic
Swift2Go
Published in
4 min readAug 24, 2018
Photo by marcos mayer on Unsplash

In my last blog, I tackled the issues of synchronizing the asynchronous tasks. I’m sure you also read the last section, where I mentioned PromiseKit and AwaitKit. As mentioned, I have my reservations over PromiseKit, although I like Promises and especially Awaits a lot!

Await made it into the Javascript with ES8 last year and it trivialised the problem from aforementioned article. I was kind of inspired by Yannick’s AwaitKit and thinking if I could do something similar to encapsulate the semaphore boilerplate and make it a bit more trivial. I have to admit I’m not in particular fan of sugar syntax and obfuscation of perfectly valid standard language/SDK/Framework features, so I was more like playing with it this time and wondered, if I can make it into something, what would be acceptable also for devs who have some prejudices over using semaphores or other paradigms directly.

3 Asynchronous Tasks with Semaphores

We have 3 async tasks, which we want to execute in a dependent way:

The result of the sum is used as a parameter in sumAndDifference and the results from the latter are used in the sumAndDifferenceAndMultiplication. According to the aforementioned blog, this could be solved easily without the “closure hell” like that:

If we look into the code, the console should print out this: 3, 6, 0, 6, 6, 0.

Tuples?

How about if the code from above would look something like this:

So, we simply pass our call as a function and we get back its results as the result of async.await.... But what have we here?? 😱 Tuples?? 😮😮 Sure, why not? This looks like we have encapsulated the whole “complexity” of the semaphores and callback parameters have magically turned into tuples.

All the “magic” comes from here, from 2 very short functions which don’t touch the logic, just place the semaphores and “translate” a callback into a tuple:

I’m sure you can easily imagine how these 2 functions are implemented in the same way for 1 and 2 callback parameters, right?

Still, this looks like it could use a lot of improvements. Yes. I tried with variadic parameters to make only these 2 functions for any kind of a number of callback parameters, but unfortunately (or logically), you can’t have non-fixed number of tuple parameters at a compile time.

I also tried to implement everything with generics, however, in a way, how I wanted this to be used, Swift can’t infer the type and compiler produces the error.
At the end, I had to settle with a pretty much good idea of injecting callback closure, one for each specific number of parameters. Which is actually not that bad. How many do you usually get from the callback? 1, 2, 3? More? Here you go! ;)

This injected callback never references callback parameters, as well as the await function never references parameters and their types. It only handles the semaphores. However, by not touching them, it is not possible for the compiler to infer the type, so we need to downcast when we use the result.

Conclusion

Not really my favourite approach, since I don’t have the issue with reading and understanding the standard code, but if I don’t have to use the complex 3rd party libs/frameworks and my “sugar” helping object is short and simple as that one, then I might even go for it myself.

If you have any idea, how to improve this, please, download the sample and play with it.

--

--