How to decide which option is better

Let's do a summary of the options that we have:

  • Sync function wrapped with a coroutine: The biggest advantage is how explicit it is, but in doing so it's quite verbose.
  • An async function with a specific dispatcher: While being less verbose, it's not as flexible because the caller can't decide which dispatcher should be used – which could be good if you really want to force the coroutine to a specific thread. Being explicit about it the function being asynchronous depends on the developer, which is less than ideal.
  • An async function with a flexible dispatcher: Allows the caller to decide where to run the coroutine, but still depends on the developer giving a proper name to the function.

The best decision depends on the specific situation, and there's no silver bullet that will be perfect for all the different scenarios. That being said, here are my takes on the issue.

  • Is there a platform limitation? We know that in Android we can't make network requests on the UI thread, so it becomes convenient to use an async function when the code is going to do networking to avoid trying to do the call in the wrong thread.
  • Is the function going to be called from many places? Having to wrap a sync function with a launch() or async() block is fine if you will do it a few times; it makes concurrency explicit while being readable enough. But, if you see yourself spraying the same snippet all over your class, it may be more readable to make it into an async function.
  • Do you want the caller to be able to decide what dispatcher should be used? In some cases, you want to enforce that certain code runs in a specific dispatcher – for example, to avoid atomicity violation– regardless of what the caller wants; in this case an async function with a specific dispatcher is the way to go.
  • Can it be guaranteed that the naming will be correct? Avoid using async functions if you know that you can't enforce all your team to prefix (or suffix) the async functions to clearly state that they are asynchronous. It's worse to have code that crashes because the naming of a concurrent function is not clear than having to be verbose when calling said function. Fixing the former will usually require more time than doing the latter, too.
  • It shouldn't be necessary for you to provide both a synchronous implementation and an asynchronous one for the same function, so avoid it at all costs. I can assure you that the bad side of both approaches will end up happening. The only exception to this could be if you are writing a library; in that case it may make sense to provide both options for flexibility and have the users decide what adjusts to their needs.
  • Avoid heavy mixing of approaches in the same project. All the approaches are valid, but try your best to stick to one through your code base for consistency. Inconsistency and lack of standards not only affect the readability of code, but are also the root of many bugs.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.135.36