<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Comunidade Dev Space</title>
    <description>The latest articles on DEV Community by Comunidade Dev Space (@comunidadedevspace).</description>
    <link>https://dev.to/comunidadedevspace</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F6381%2Ff7d97655-a406-40e6-87d5-affc3b971ef6.png</url>
      <title>DEV Community: Comunidade Dev Space</title>
      <link>https://dev.to/comunidadedevspace</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/comunidadedevspace"/>
    <language>en</language>
    <item>
      <title>Optimizing Asynchronous Programming with Flows in Kotlin: Introduction to Flow</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 27 Mar 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/optimizing-asynchronous-programming-with-flows-in-kotlin-introduction-to-flow-7ji</link>
      <guid>https://dev.to/comunidadedevspace/optimizing-asynchronous-programming-with-flows-in-kotlin-introduction-to-flow-7ji</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As the complexity of applications grows, handling multiple asynchronous events in real time becomes essential. To this end, Kotlin offers a powerful tool called &lt;strong&gt;&lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;, which simplifies the management of asynchronous data flows.&lt;/p&gt;

&lt;p&gt;In this article, we will explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is a &lt;code&gt;Flow&lt;/code&gt; and how does it differ from other approaches like &lt;code&gt;suspend&lt;/code&gt; and &lt;code&gt;async&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;Real use cases of &lt;code&gt;Flow&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tools like &lt;strong&gt;Turbine&lt;/strong&gt; to test data flows.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – What is a &lt;code&gt;Flow&lt;/code&gt;?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Kotlin Flow is a tool for handling asynchronous data flows. It works like a pipeline that emits values over time, allowing you to handle data streams efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Main Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous:&lt;/strong&gt; &lt;code&gt;Flow&lt;/code&gt; emits values in a non-blocking manner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold Stream :&lt;/strong&gt; A &lt;code&gt;Flow&lt;/code&gt; only starts emitting values when there is a "sink" (i.e. when someone consumes the data).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cancellable:&lt;/strong&gt; If the collector is canceled, the flow is also automatically canceled.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Creating a &lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Simple Example of a &lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Emits a value&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates a delay between emissions&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received: $value"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Console Output&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Received: 1&lt;br&gt;
Received: 2&lt;br&gt;
Received: 3&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;emit&lt;/code&gt;: Sends values to the stream.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;collect&lt;/code&gt;: Consumes the values emitted by the stream.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4 – Comparison: Flow vs. Other Approaches&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Appearance&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Flow&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;suspend&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;async&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Continuous data flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multiple values&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (only one value per call)&lt;/td&gt;
&lt;td&gt;No (returns a single value).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cancellable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Typical example&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Event streams&lt;/td&gt;
&lt;td&gt;Simple asynchronous calls&lt;/td&gt;
&lt;td&gt;Parallel computations.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Transforming Data with &lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The real power of &lt;code&gt;Flow&lt;/code&gt; lies in its ability to transform the data output with operators.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example: Using operators like &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;flow&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Filter even values&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Multiplies the values by 10&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Transformed: $value"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Console Output&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Transformed: 20&lt;br&gt;
Transformed: 40&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6 – Testing Flows with Turbine&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Turbine&lt;/strong&gt; is a library that facilitates the validation of values emitted by a &lt;code&gt;Flow&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example with Turbine&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;app.cash.turbine.test&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// Creates a stream that emits two values with a delay between them&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Emitting value 1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Emit the first value&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Wait 500ms&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Emitting value 2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Emit the second value&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Test the flow&lt;/span&gt;
    &lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;firstValue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;awaitItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Wait for the first value&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value received from stream: $ firstValue "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firstValue&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Validates the first value&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;secondValue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;awaitItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Wait for the second value&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value received from stream: $ secondValue "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secondValue&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Validates the second value&lt;/span&gt;

        &lt;span class="nf"&gt;awaitComplete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Check if the stream has completed&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Flow completed successfully!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected departure at terminal&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Emitting value 1&lt;br&gt;
Value received from stream: 1&lt;br&gt;
Emitting value 2&lt;br&gt;
Value received from stream: 2&lt;br&gt;
Flow completed successfully!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;7 – Real Use Cases of &lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;7.1 – Real Time Update&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In a chat application, you can use a &lt;code&gt;Flow&lt;/code&gt; to stream new messages to the user interface as they arrive from the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;messages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;newMessages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"How are you?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"See you soon!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;newMessages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates interval between messages&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"New message: $message"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;7.2 – Batch Data Processing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine a system that needs to process large batches of data at regular intervals. &lt;code&gt;Flow&lt;/code&gt; makes this implementation easy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;batchFlow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;lots&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lot1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lot2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lot3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lot&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lots&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;issue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates processing time&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;batchFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lot&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing: $batch"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;8 – Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Flow&lt;/code&gt; is a powerful tool for handling asynchronous data in Kotlin , allowing you to emit, transform, and consume values in real time. It is essential for building modern applications, especially in scenarios that require handling continuous streams of events.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Flow&lt;/code&gt; is ideal for continuous, cancelable data streams.&lt;/li&gt;
&lt;li&gt;Operators like &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; make it easier to transform the outputted data.&lt;/li&gt;
&lt;li&gt;Tools like Turbine simplify flow testing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Official Kotlin documentation on coroutines&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cashapp/turbine" rel="noopener noreferrer"&gt;Turbine Documentation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>flow</category>
      <category>coroutines</category>
      <category>async</category>
    </item>
    <item>
      <title>Otimizando Programação Assíncrona com Fluxos no Kotlin: Introdução ao `Flow`</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 27 Mar 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/otimizando-programacao-assincrona-com-fluxos-no-kotlin-introducao-ao-flow-28m9</link>
      <guid>https://dev.to/comunidadedevspace/otimizando-programacao-assincrona-com-fluxos-no-kotlin-introducao-ao-flow-28m9</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;À medida que a complexidade das aplicações cresce, lidar com múltiplos eventos assíncronos em tempo real se torna essencial. Para isso, o Kotlin oferece uma poderosa ferramenta chamada &lt;strong&gt;&lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;, que simplifica o gerenciamento de fluxos de dados assíncronos.&lt;/p&gt;

&lt;p&gt;Neste artigo, exploraremos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O que é um &lt;code&gt;Flow&lt;/code&gt; e como ele difere de outras abordagens como &lt;code&gt;suspend&lt;/code&gt; e &lt;code&gt;async&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Casos reais de uso de &lt;code&gt;Flow&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ferramentas como o &lt;strong&gt;Turbine&lt;/strong&gt; para testar fluxos de dados.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – O Que é um &lt;code&gt;Flow&lt;/code&gt;?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Um &lt;strong&gt;&lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt; no Kotlin é uma &lt;strong&gt;ferramenta para lidar com fluxos de dados assíncronos&lt;/strong&gt;. Ele funciona como um pipeline que emite valores ao longo do tempo, permitindo que você lide com streams de dados de forma eficiente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Características principais:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Assíncrono:&lt;/strong&gt; O &lt;code&gt;Flow&lt;/code&gt; emite valores de forma não bloqueante.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold Stream:&lt;/strong&gt; Um &lt;code&gt;Flow&lt;/code&gt; só começa a emitir valores quando há um "coletor" (ou seja, quando alguém consome os dados).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cancelável:&lt;/strong&gt; Se o coletor for cancelado, o fluxo também é cancelado automaticamente.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Criando um &lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Exemplo Simples de um &lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fluxo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Emite um valor&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula um intervalo entre emissões&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fluxo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Recebido: $valor"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Saída no console&lt;/strong&gt;  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recebido: 1&lt;br&gt;
Recebido: 2&lt;br&gt;
Recebido: 3&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Explicação:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;emit&lt;/code&gt;: Envia valores para o fluxo.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;collect&lt;/code&gt;: Consome os valores emitidos pelo fluxo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4 – Comparação: Flow vs. Outras Abordagens&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspecto&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Flow&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;suspend&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;async&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fluxo de dados contínuo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Não&lt;/td&gt;
&lt;td&gt;Não&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multiplos valores&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Não (apenas um valor por chamada)&lt;/td&gt;
&lt;td&gt;Não (retorna um único valor).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cancelável&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exemplo típico&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Streams de eventos&lt;/td&gt;
&lt;td&gt;Chamadas assíncronas simples&lt;/td&gt;
&lt;td&gt;Cálculos paralelos.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Transformando Dados com &lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O verdadeiro poder do &lt;code&gt;Flow&lt;/code&gt; está em sua capacidade de transformar os dados emitidos com operadores.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Exemplo: Usando operadores como &lt;code&gt;map&lt;/code&gt; e &lt;code&gt;filter&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fluxo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fluxo&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Filtra valores pares&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Multiplica os valores por 10&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;valor&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Transformado: $valor"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Saída no console&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Transformado: 20&lt;br&gt;
Transformado: 40&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6 – Testando Fluxos com Turbine&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;Turbine&lt;/strong&gt; é uma biblioteca que facilita a validação de valores emitidos por um &lt;code&gt;Flow&lt;/code&gt;.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Exemplo com Turbine&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;app.cash.turbine.test&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Cria um fluxo que emite dois valores com um atraso entre eles&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fluxo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Emitindo valor 1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Emite o primeiro valor&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Aguarda 500ms&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Emitindo valor 2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Emite o segundo valor&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Testa o fluxo&lt;/span&gt;
    &lt;span class="n"&gt;fluxo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;primeiroValor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;awaitItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Aguarda o primeiro valor&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Valor recebido do fluxo: $primeiroValor"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;primeiroValor&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Valida o primeiro valor&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;segundoValor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;awaitItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Aguarda o segundo valor&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Valor recebido do fluxo: $segundoValor"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;segundoValor&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Valida o segundo valor&lt;/span&gt;

        &lt;span class="nf"&gt;awaitComplete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Verifica se o fluxo foi concluído&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fluxo concluido com sucesso!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Saída esperada no terminal&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Emitindo valor 1&lt;br&gt;
Valor recebido do fluxo: 1&lt;br&gt;
Emitindo valor 2&lt;br&gt;
Valor recebido do fluxo: 2&lt;br&gt;
Fluxo concluido com sucesso!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;7 – Casos Reais de Uso do &lt;code&gt;Flow&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;7.1 – Atualização em Tempo Real&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Em um aplicativo de bate-papo, você pode usar um &lt;code&gt;Flow&lt;/code&gt; para transmitir mensagens novas à interface do usuário conforme elas chegam do servidor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;mensagens&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;novasMensagens&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Oi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Como você está?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Até logo!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mensagem&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;novasMensagens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mensagem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula intervalo entre mensagens&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;mensagens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mensagem&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nova mensagem: $mensagem"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;7.2 – Processamento de Dados em Lotes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine um sistema que precisa processar lotes de dados grandes em intervalos regulares. O &lt;code&gt;Flow&lt;/code&gt; facilita essa implementação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fluxoDeLotes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;lotes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lote1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lote2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lote3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lote&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lotes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lote&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula tempo de processamento&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fluxoDeLotes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lote&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processando: $lote"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;8 – Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;Flow&lt;/code&gt; é uma ferramenta poderosa para lidar com dados assíncronos no Kotlin, permitindo a emissão, transformação e consumo de valores em tempo real. Ele é essencial para construir aplicações modernas, especialmente em cenários que exigem a manipulação de streams contínuos de eventos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumo:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O &lt;code&gt;Flow&lt;/code&gt; é ideal para fluxos de dados contínuos e canceláveis.
&lt;/li&gt;
&lt;li&gt;Operadores como &lt;code&gt;map&lt;/code&gt; e &lt;code&gt;filter&lt;/code&gt; facilitam a transformação dos dados emitidos.
&lt;/li&gt;
&lt;li&gt;Ferramentas como o Turbine simplificam os testes de fluxos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Referências:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Documentação oficial do Kotlin sobre corrotinas&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cashapp/turbine" rel="noopener noreferrer"&gt;Documentação do Turbine&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>flow</category>
      <category>coroutines</category>
      <category>async</category>
    </item>
    <item>
      <title>Asynchronous Programming in Practice with Kotlin: Real Examples and Optimization</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 20 Mar 2025 08:40:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/asynchronous-programming-in-practice-with-kotlin-real-examples-and-optimization-2c01</link>
      <guid>https://dev.to/comunidadedevspace/asynchronous-programming-in-practice-with-kotlin-real-examples-and-optimization-2c01</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Understanding the concepts of asynchronous programming is essential, but applying these concepts in real-world scenarios is where things really come to life. In this article, we will explore practical examples of how asynchronous programming can be used to optimize tasks and improve the performance of Kotlin applications .&lt;/p&gt;

&lt;p&gt;We will use the examples from &lt;strong&gt;Synchronous vs. Asynchronous Café&lt;/strong&gt; as a basis, showing the benefits of thinking asynchronously to solve everyday problems for a developer.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – Problem Review: Blocking Tasks&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In a synchronous workflow, each task depends on the completion of the previous one. This means that the total execution time is the sum of the time of all tasks. On the other hand, asynchronous programming allows multiple tasks to be performed simultaneously, drastically reducing the total execution time.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example: Brewing Synchronous Coffee&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;makeSynchronousCafe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Coffee finished."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;makeSynchronousCafe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Getting water..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates the time to get the water&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Boiling water..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates the time to boil water&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Making coffee..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates the time to brew the coffee&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Console Output&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Getting the water...&lt;br&gt;
Boiling water...&lt;br&gt;
Making coffee...&lt;br&gt;
Coffee finished.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem&lt;/strong&gt;: All tasks are done in sequence. Total execution time is 4 seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Solution: Asynchronous Coffee&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With asynchronous programming, we can perform parallel tasks, such as boiling water while preparing the filter, reducing the total execution time.&lt;br&gt;
&lt;strong&gt;Example: Brewing Asynchronous Coffee&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;water&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;boilWater&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;prepareFilter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;water&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Wait for the water to be ready&lt;/span&gt;
    &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Wait for the filter to be ready&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Making coffee..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates the time to brew the coffee&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Coffee finished."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;boilWater&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Getting water..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates the time to get the water&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Boiling water..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates the time to boil water&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;prepareFilter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Preparing the filter and powder..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates the time to prepare the filter&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Console Output&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Getting the water...&lt;br&gt;
Preparing the filter and powder...&lt;br&gt;
Boiling water...&lt;br&gt;
Making coffee...&lt;br&gt;
Coffee finished.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4 – Real Cases of Asynchronous Programming&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4.1 – Loading Data into Applications&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine an application that needs to load data from multiple APIs to build an interface.&lt;br&gt;
With synchronous programming, each request would be made one after the other, increasing the waiting time. Using coroutines , all requests can be made simultaneously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;api1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;loadApiData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API 1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;api2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;loadApiData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API 2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Loading data..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;loadApiData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates API response time&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"$api: Data loaded"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;4.2 - File Processing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When processing multiple large files, such as logs or images, coroutines can help divide and parallelize the work, reducing the overall processing time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;files&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File1.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"File2.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"File3.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="nf"&gt;files&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;processFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;processFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing $name..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates processing time&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$name processed!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Benefits of Thinking Asynchronously&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Time efficiency&lt;/strong&gt;: Parallel tasks reduce total execution time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better user experience&lt;/strong&gt;: More responsive and faster apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimal use of resources&lt;/strong&gt;: Makes better use of available processing power.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6 – Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Asynchronous programming is an essential skill for any developer who wants to build efficient and modern applications. Using coroutines in Kotlin allows you to handle complex tasks in a simple and scalable way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The coffee example shows how parallel tasks optimize execution time.&lt;/li&gt;
&lt;li&gt;Real-world cases like API loading and file processing highlight the practical benefits of coroutines .&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the next article, we will discuss how to integrate these concepts with Flow and how to further optimize your asynchronous programming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Official Kotlin documentation on coroutines&lt;/a&gt;&lt;/p&gt;

</description>
      <category>coroutines</category>
      <category>async</category>
      <category>programming</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Programação Assíncrona na Prática com Kotlin: Exemplos Reais e Otimização</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 20 Mar 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/programacao-assincrona-na-pratica-com-kotlin-exemplos-reais-e-otimizacao-5d30</link>
      <guid>https://dev.to/comunidadedevspace/programacao-assincrona-na-pratica-com-kotlin-exemplos-reais-e-otimizacao-5d30</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Entender os conceitos de programação assíncrona é essencial, mas aplicar esses conceitos em cenários reais é onde as coisas realmente ganham vida. Neste artigo, exploraremos exemplos práticos de como a programação assíncrona pode ser usada para otimizar tarefas e melhorar a performance de aplicações no Kotlin.&lt;/p&gt;

&lt;p&gt;Usaremos como base os exemplos do &lt;strong&gt;Café Síncrono vs. Assíncrono&lt;/strong&gt;, mostrando os benefícios de pensar assincronamente para resolver problemas do dia a dia de um desenvolvedor.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – Revisão do Problema: Tarefas Bloqueantes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Em um fluxo síncrono, cada tarefa depende da conclusão da anterior. Isso significa que o tempo total de execução é a soma do tempo de todas as tarefas. Por outro lado, a programação assíncrona permite que múltiplas tarefas sejam realizadas simultaneamente, reduzindo drasticamente o tempo total de execução.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Exemplo: Preparando Café Síncrono&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fazerCafeSincrono&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Café finalizado."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fazerCafeSincrono&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pegando a água..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo para pegar a água&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fervendo a água..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo para ferver a água&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Passando o café..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo para passar o café&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Saída no console&lt;/strong&gt;  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pegando a água...&lt;br&gt;
Fervendo a água...&lt;br&gt;
Passando o café...&lt;br&gt;
Café finalizado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problema&lt;/strong&gt;: Todas as tarefas são feitas em sequência. O tempo total de execução é 4 segundos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Solução: Café Assíncrono&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Com a programação assíncrona, podemos realizar tarefas paralelas, como ferver a água enquanto preparamos o filtro, reduzindo o tempo total de execução.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Exemplo: Preparando Café Assíncrono&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;agua&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;ferverAgua&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;filtro&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;prepararFiltro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;agua&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Aguarda a água estar pronta&lt;/span&gt;
    &lt;span class="n"&gt;filtro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Aguarda o filtro estar pronto&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Passando o café..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo para passar o café&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Café finalizado."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;ferverAgua&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Pegando a água..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo para pegar a água&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fervendo a água..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo para ferver a água&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;prepararFiltro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Preparando o filtro e o pó..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo para preparar o filtro&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Saída no console&lt;/strong&gt;  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pegando a água...&lt;br&gt;
Preparando o filtro e o pó...&lt;br&gt;
Fervendo a água...&lt;br&gt;
Passando o café...&lt;br&gt;
Café finalizado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4 – Casos Reais de Programação Assíncrona&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4.1 – Carregamento de Dados em Aplicativos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine um aplicativo que precisa carregar dados de múltiplas APIs para montar uma interface.&lt;br&gt;&lt;br&gt;
Com programação síncrona, cada requisição seria feita uma após a outra, aumentando o tempo de espera. Usando corrotinas, todas as requisições podem ser feitas simultaneamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;api1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;carregarDadosDeApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API 1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;api2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;carregarDadosDeApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API 2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Carregando dados..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;carregarDadosDeApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo de resposta da API&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"$api: Dados carregados"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;4.2 - Processamento de Arquivos&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ao processar múltiplos arquivos grandes, como logs ou imagens, corrotinas podem ajudar a dividir e paralelizar o trabalho, reduzindo o tempo total de processamento.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;arquivos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Arquivo1.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Arquivo2.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Arquivo3.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;arquivos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;arquivo&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;processarArquivo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arquivo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;processarArquivo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processando $nome..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula o tempo de processamento&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$nome processado!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Benefícios de Pensar Assincronamente&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Eficiência de tempo&lt;/strong&gt;: Tarefas paralelas reduzem o tempo total de execução.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Melhor experiência do usuário&lt;/strong&gt;: Aplicativos mais responsivos e rápidos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uso ideal de recursos&lt;/strong&gt;: Aproveita melhor o poder de processamento disponível.
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6 – Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A programação assíncrona é uma habilidade essencial para qualquer desenvolvedor que deseja criar aplicações eficientes e modernas. Usar corrotinas no Kotlin permite que você lide com tarefas complexas de forma simples e escalável.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumo&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O exemplo do café mostra como tarefas paralelas otimizam o tempo de execução.
&lt;/li&gt;
&lt;li&gt;Casos reais, como carregamento de APIs e processamento de arquivos, destacam os benefícios práticos das corrotinas.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No próximo artigo, discutiremos como integrar esses conceitos com fluxos (Flow) e como otimizar ainda mais sua programação assíncrona.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referência&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Documentação oficial do Kotlin sobre corrotinas&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>async</category>
      <category>programming</category>
    </item>
    <item>
      <title>Unit Testing with Coroutines in Kotlin: Tools and Best Practices</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 13 Mar 2025 08:40:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/unit-testing-with-coroutines-in-kotlin-tools-and-best-practices-3dod</link>
      <guid>https://dev.to/comunidadedevspace/unit-testing-with-coroutines-in-kotlin-tools-and-best-practices-3dod</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Testing asynchronous code can be challenging. Functions that use coroutines can have unpredictable behavior due to delays, concurrent execution, and context switches. Fortunately, Kotlin provides built-in tools and helper libraries to simplify unit testing with coroutines .&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to use tools like &lt;strong&gt;&lt;code&gt;UnconfinedTestDispatcher&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;TestCoroutineScheduler&lt;/code&gt;&lt;/strong&gt;, and the &lt;strong&gt;Turbine&lt;/strong&gt; library to efficiently test coroutines and flows.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – The Problem of Testing Asynchronous Code&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Testing asynchronous code is tricky because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Coroutines can run in different threads or contexts.&lt;/li&gt;
&lt;li&gt;Methods like &lt;code&gt;delay&lt;/code&gt; or &lt;code&gt;withTimeout&lt;/code&gt; introduce real waits that can slow down tests.&lt;/li&gt;
&lt;li&gt;Flows depend on asynchronous events that need to be controlled.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without the right tools, tests can become flaky or take longer than necessary.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3 - Kotlin Native Tools&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 – UnconfinedTestDispatcher&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
A dispatcher designed for testing that is not tied to specific threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why use it?&lt;/strong&gt;
Allows you to run coroutines without context restrictions, making tests predictable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// The testScheduler is a TestCoroutineScheduler automatically provided by runTest .&lt;/span&gt;
&lt;span class="c1"&gt;// It manages virtual time for all coroutines in this test.&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;testDispatcher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UnconfinedTestDispatcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testScheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// We use testDispatcher to ensure that all operations share not only the same scheduler , but also the same dispatcher .&lt;/span&gt;
    &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testDispatcher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" Running in UnconfinedTestDispatcher : ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates a virtual 1 second delay&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finalizing in UnconfinedTestDispatcher ."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.2 – TestCoroutineScheduler&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
A scheduler that allows you to manually advance time in tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why use it?&lt;/strong&gt;
To control time-based tasks (&lt;code&gt;delay&lt;/code&gt;, &lt;code&gt;withTimeout&lt;/code&gt;) without waiting for real time to pass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoroutinesTests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a TestCoroutineScheduler manually&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;scheduler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TestCoroutineScheduler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a dispatcher based on the manual scheduler&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;testDispatcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TestDispatcher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UnconfinedTestDispatcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;testCoroutines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// Use runTest with the dispatcher configured&lt;/span&gt;
        &lt;span class="nf"&gt;runTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testDispatcher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task started."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Launch a coroutine in the same dispatcher&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates a virtual 1 second delay&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task completed."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Advance time virtually by 1 second&lt;/span&gt;
            &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;advanceTimeBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why do we need &lt;code&gt;@Test&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;@Test&lt;/code&gt; annotation is used to mark a method as a &lt;strong&gt;test case&lt;/strong&gt;, allowing it to be executed by JUnit.&lt;/li&gt;
&lt;li&gt;Without &lt;code&gt;@Test&lt;/code&gt;, the testCoroutines method would be treated as a normal method and &lt;strong&gt;would not appear as executable in the IDE&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;When JUnit detects &lt;code&gt;@Test&lt;/code&gt;, it:

&lt;ol&gt;
&lt;li&gt;Automatically instantiate the test class.&lt;/li&gt;
&lt;li&gt;Execute the marked method, with all dependencies configured (such as &lt;code&gt;scheduler&lt;/code&gt; and &lt;code&gt;testDispatcher&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.3 – runTest&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
A function that provides a controlled environment for running coroutines in tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why use it?&lt;/strong&gt;
Simplifies the setup of asynchronous tests by replacing &lt;code&gt;runBlocking&lt;/code&gt; in tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting test."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// This does not delay the actual test&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test completed."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;4 - Testing flows with the turbine library&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For Flows, the Turbine library simplifies the collection and validation of emitted values.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4.1 – What is Turbine?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Turbine is a library designed specifically for testing flows in Kotlin , allowing you to validate emitted items and events like cancellation or completion.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example with turbine:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;app.cash.turbine.test&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.delay&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.flow&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.runTest&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;item1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;awaitItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received: $item1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Display the first value on the terminal&lt;/span&gt;
        &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Validate the first item&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;item2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;awaitItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received: $item2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Display the second value on the terminal&lt;/span&gt;
        &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item2&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Validate the second item&lt;/span&gt;

        &lt;span class="nf"&gt;awaitComplete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Confirms that the flow has completed&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Flow completed !"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Indicates that the flow has finished&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Tool Comparison&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Tool&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;When to use&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UnconfinedTestDispatcher&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runs coroutines without context restrictions.&lt;/td&gt;
&lt;td&gt;Simple tests that do not rely on real-time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TestCoroutineScheduler&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manually controls timing in tests.&lt;/td&gt;
&lt;td&gt;Tests with &lt;code&gt;delay&lt;/code&gt;, &lt;code&gt;timeout&lt;/code&gt;, or time events.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Turbine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tests values emitted by &lt;code&gt;Flow&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;Flow-specific tests.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;6 – Conclusion&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Testing coroutines and flows in Kotlin can be challenging, but with the right tools, you can create fast, efficient, and reliable tests. Using &lt;code&gt;UnconfinedTestDispatcher&lt;/code&gt; , &lt;code&gt;TestCoroutineScheduler&lt;/code&gt; , and libraries like Turbine makes the process much simpler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Time tracking&lt;/strong&gt;: Use TestCoroutineScheduler to manage delays and scheduling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test environments&lt;/strong&gt;: runTest is the basis for asynchronous testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flow Testing&lt;/strong&gt;: Turbine is the ideal solution for validating flows.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you know the best practices for testing coroutines in Kotlin , try applying them to your projects!&lt;/p&gt;

&lt;p&gt;In the next article, we will discuss a little more about examples of asynchrony, just to explore the subject a little more and fix the content better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Official Kotlin documentation on coroutines&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cashapp/turbine" rel="noopener noreferrer"&gt;Turbine Documentation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>testing</category>
      <category>flow</category>
    </item>
    <item>
      <title>Testes Unitários com Corrotinas no Kotlin: Ferramentas e Boas Práticas</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 13 Mar 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/testes-unitarios-com-corrotinas-no-kotlin-ferramentas-e-boas-praticas-4100</link>
      <guid>https://dev.to/comunidadedevspace/testes-unitarios-com-corrotinas-no-kotlin-ferramentas-e-boas-praticas-4100</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Testar código assíncrono é, muitas vezes, um desafio. Funções que utilizam corrotinas podem ter comportamento imprevisível devido a atrasos, execução concorrente e mudanças de contexto. Felizmente, o Kotlin oferece ferramentas nativas e bibliotecas auxiliares para simplificar os testes unitários com corrotinas.&lt;/p&gt;

&lt;p&gt;Neste artigo, exploraremos como usar ferramentas como &lt;strong&gt;&lt;code&gt;UnconfinedTestDispatcher&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;TestCoroutineScheduler&lt;/code&gt;&lt;/strong&gt;, e a biblioteca &lt;strong&gt;Turbine&lt;/strong&gt; para testar corrotinas e fluxos de forma eficiente.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – O Problema de Testar Código Assíncrono&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Testar código assíncrono é complicado porque:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Corrotinas podem ser executadas em diferentes threads ou contextos.
&lt;/li&gt;
&lt;li&gt;Métodos como &lt;code&gt;delay&lt;/code&gt; ou &lt;code&gt;withTimeout&lt;/code&gt; introduzem esperas reais que podem tornar os testes lentos.
&lt;/li&gt;
&lt;li&gt;Fluxos (&lt;code&gt;Flow&lt;/code&gt;) dependem de eventos assíncronos que precisam ser controlados.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sem as ferramentas corretas, testes podem se tornar &lt;strong&gt;inconsistentes (flaky)&lt;/strong&gt; ou levar mais tempo do que o necessário.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Ferramentas Nativas do Kotlin&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 – UnconfinedTestDispatcher&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Um dispatcher projetado para testes que não está vinculado a threads específicas.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Por que usar?&lt;/strong&gt;
Permite executar corrotinas sem restrições de contexto, tornando os testes previsíveis.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// O testScheduler é um TestCoroutineScheduler fornecido automaticamente pelo runTest.&lt;/span&gt;
    &lt;span class="c1"&gt;// Ele gerencia o tempo virtual para todas as corrotinas neste teste.&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;testDispatcher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UnconfinedTestDispatcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testScheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Utilizamos o testDispatcher para garantir que todas as operações compartilhem além do mesmo scheduler, também o mesmo dispatcher.&lt;/span&gt;
    &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testDispatcher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando no UnconfinedTestDispatcher: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula um atraso de 1 segundo virtual&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finalizando no UnconfinedTestDispatcher."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.2 – TestCoroutineScheduler&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Um agendador que permite avançar o tempo manualmente em testes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Por que usar?&lt;/strong&gt;
Para controlar tarefas baseadas em tempo (&lt;code&gt;delay&lt;/code&gt;, &lt;code&gt;withTimeout&lt;/code&gt;) sem esperar o tempo real passar.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestesCoroutines&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Cria um TestCoroutineScheduler manualmente&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;scheduler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TestCoroutineScheduler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// Cria um dispatcher baseado no scheduler manual&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;testDispatcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TestDispatcher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UnconfinedTestDispatcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;testCoroutines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Usa runTest com o dispatcher configurado&lt;/span&gt;
        &lt;span class="nf"&gt;runTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testDispatcher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tarefa iniciada."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;// Lança uma corrotina no mesmo dispatcher&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula um atraso de 1 segundo virtual&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tarefa concluída."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;// Avança o tempo virtualmente em 1 segundo&lt;/span&gt;
            &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;advanceTimeBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Por que precisamos do &lt;code&gt;@Test&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A anotação &lt;code&gt;@Test&lt;/code&gt; é usada para marcar um método como um &lt;strong&gt;caso de teste&lt;/strong&gt;, permitindo que ele seja executado pelo JUnit.&lt;/li&gt;
&lt;li&gt;Sem o &lt;code&gt;@Test&lt;/code&gt;, o método testCoroutines seria tratado como um método normal e &lt;strong&gt;não apareceria como executável no IDE&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Quando o JUnit detecta o &lt;code&gt;@Test&lt;/code&gt;, ele:

&lt;ol&gt;
&lt;li&gt;Instancia automaticamente a classe de teste.&lt;/li&gt;
&lt;li&gt;Executa o método marcado, com todas as dependências configuradas (como &lt;code&gt;scheduler&lt;/code&gt; e &lt;code&gt;testDispatcher&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.3 – runTest&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Uma função que fornece um ambiente controlado para executar corrotinas em testes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Por que usar?&lt;/strong&gt;
Simplifica a configuração de testes assíncronos, substituindo &lt;code&gt;runBlocking&lt;/code&gt; em testes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Iniciando o teste."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Isso não atrasa o teste real&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Teste finalizado."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;4 - Testando fluxos com a biblioteca turbine&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para fluxos (Flow), a biblioteca Turbine simplifica a coleta e validação de valores emitidos.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4.1 – O que é Turbine?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Turbine é uma biblioteca projetada especificamente para testar fluxos no Kotlin, permitindo validar os itens emitidos e eventos como cancelamento ou conclusão.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo com turbine:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;app.cash.turbine.test&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.delay&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.flow.flow&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.test.runTest&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fluxo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fluxo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;item1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;awaitItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Recebido: $item1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Exibe o primeiro valor no terminal&lt;/span&gt;
        &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Valida o primeiro item&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;item2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;awaitItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Recebido: $item2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Exibe o segundo valor no terminal&lt;/span&gt;
        &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item2&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Valida o segundo item&lt;/span&gt;

        &lt;span class="nf"&gt;awaitComplete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Confirma que o fluxo foi concluído&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fluxo concluido!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Indica que o fluxo terminou&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Comparação de Ferramentas&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Ferramenta&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Função&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Quando usar&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UnconfinedTestDispatcher&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Executa corrotinas sem restrições de contexto.&lt;/td&gt;
&lt;td&gt;Testes simples que não dependem de tempo real.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TestCoroutineScheduler&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Controla tempo manualmente em testes.&lt;/td&gt;
&lt;td&gt;Testes com &lt;code&gt;delay&lt;/code&gt;, &lt;code&gt;timeout&lt;/code&gt;, ou eventos de tempo.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Turbine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Testa valores emitidos por &lt;code&gt;Flow&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;Testes específicos de fluxos.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;6 – Conclusão&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Testar corrotinas e fluxos no Kotlin pode ser desafiador, mas com as ferramentas certas, é possível criar testes rápidos, eficientes e confiáveis. O uso de &lt;code&gt;UnconfinedTestDispatcher&lt;/code&gt;, &lt;code&gt;TestCoroutineScheduler&lt;/code&gt;, e bibliotecas como o Turbine torna o processo muito mais simples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumo:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Controle de tempo&lt;/strong&gt;: Use TestCoroutineScheduler para gerenciar atrasos e agendamentos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ambientes de teste&lt;/strong&gt;: runTest é a base para testes assíncronos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testes de fluxo&lt;/strong&gt;: Turbine é a solução ideal para validar fluxos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Agora que você conhece as melhores práticas para testar corrotinas no Kotlin, experimente aplicá-las nos seus projetos!&lt;/p&gt;

&lt;p&gt;No próximo artigo, iremos discorrer um pouquinho mais a respeito de exemplos de assincronia, somente para explorarmos o assunto um pouco mais e fixarmos o conteúdo melhor.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>testing</category>
      <category>flow</category>
    </item>
    <item>
      <title>Utility and Execution Methods in Kotlin: Working with Coroutines</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 06 Mar 2025 08:40:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/utility-and-execution-methods-in-kotlin-working-with-coroutines-15cb</link>
      <guid>https://dev.to/comunidadedevspace/utility-and-execution-methods-in-kotlin-working-with-coroutines-15cb</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When working with coroutines in Kotlin , there are &lt;strong&gt;utility methods&lt;/strong&gt; and &lt;strong&gt;execution methods&lt;/strong&gt; that help you manage asynchronous tasks efficiently. These methods are essential tools for controlling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The execution time of the tasks.&lt;/li&gt;
&lt;li&gt;The context in which tasks are performed.&lt;/li&gt;
&lt;li&gt;Starting and synchronizing multiple coroutines .&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we will explore the most important methods, such as &lt;code&gt;withTimeout&lt;/code&gt;, &lt;code&gt;withContext&lt;/code&gt;, &lt;code&gt;launch&lt;/code&gt;, &lt;code&gt;async&lt;/code&gt;, and others, with practical examples to understand how and when to use them.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – Utility Methods&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2.1 – withTimeout&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Cancels the execution of a block of code if the timeout is reached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
To prevent asynchronous tasks from getting stuck indefinitely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;withTimeout&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 1 second timeout&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates a long task&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"Task completed!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TimeoutCancellationException&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"Timeout reached! Task canceled."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2.2 - withTimeoutOrNull&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Similar to &lt;code&gt;withTimeout&lt;/code&gt; , but instead of throwing an exception, it returns null if the timeout is reached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
To avoid using exceptions and handle timeout in a more controlled way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withTimeoutOrNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 1 second timeout&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simulates a long task&lt;/span&gt;
        &lt;span class="s"&gt;"Job completed!"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Timeout reached! Returned null ."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2.3 – withContext&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Changes the context of the coroutine (e.g.: changes the dispatcher ).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
temporarily change the dispatcher within a coroutine .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines&lt;/span&gt; &lt;span class="p"&gt;.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" Running on Default Dispatcher : ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" Running in IO Dispatcher: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Back to Default Dispatcher : ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2.4 – delay&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Suspends the execution of a coroutine for a period of time, without blocking the thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
To simulate time-consuming tasks or wait for a response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting task..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Suspend for 1 second&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task completed!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2.5 – yield&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Yields the current context, allowing other coroutines to run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
To improve cooperation between coroutines and avoid unnecessary blocking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" Coroutine 1 - Iteration $i"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Yield the context&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" Coroutine 2 - Iteration $i"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Yield the context&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Execution Methods&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 – launch&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Creates a new coroutine and starts its execution immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
When you don't need to return a result from the coroutine .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Coroutine started!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Coroutine finished!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.2 – async&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Creates a new coroutine that returns a value (deferred).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
For asynchronous tasks that return results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="s"&gt;"Result calculated!"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Waiting for result..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result:${result.await()}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.3 – runBlocking&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Executes coroutines in a blocking function.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
Only in specific cases, such as small scripts or for quick testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting runBlocking"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finalizing runBlocking"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;4 – Comparison: Utility Methods vs. Execution Methods&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspect&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Utility Methods&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Execution Methods&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Main Function&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Control time, context, and suspension.&lt;/td&gt;
&lt;td&gt;Start and manage coroutines.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Return Value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generally, they do not return values.&lt;/td&gt;
&lt;td&gt;Some return values (e.g. &lt;code&gt;async&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Main Examples&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;withTimeout&lt;/code&gt;, &lt;code&gt;delay&lt;/code&gt;, &lt;code&gt;yield&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;launch&lt;/code&gt;, &lt;code&gt;async&lt;/code&gt;, &lt;code&gt;runBlocking&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Utility and runner methods are indispensable tools in the Kotlin coroutine ecosystem. They allow you to control asynchronous execution in a precise, scalable, and efficient way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary of Methods:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Utilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Timeout control&lt;/strong&gt;: &lt;code&gt;withTimeout&lt;/code&gt;, &lt;code&gt;withTimeoutOrNull&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt;: &lt;code&gt;withContext&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suspension&lt;/strong&gt;: &lt;code&gt;delay&lt;/code&gt;, &lt;code&gt;yield&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Execution:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;launch&lt;/code&gt;&lt;/strong&gt; for coroutines that do not return values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; for coroutines that return results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;runBlocking&lt;/code&gt;&lt;/strong&gt; to run coroutines in scripts or simple tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next article, we will explore how to efficiently test coroutines and flows with native tools and libraries like Turbine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Official Kotlin documentation on coroutines&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>async</category>
      <category>programming</category>
    </item>
    <item>
      <title>Métodos Utilitários e de Execução no Kotlin: Trabalhando com Corrotinas</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 06 Mar 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/metodos-utilitarios-e-de-execucao-no-kotlin-trabalhando-com-corrotinas-12j6</link>
      <guid>https://dev.to/comunidadedevspace/metodos-utilitarios-e-de-execucao-no-kotlin-trabalhando-com-corrotinas-12j6</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ao trabalhar com corrotinas no Kotlin, existem &lt;strong&gt;métodos utilitários&lt;/strong&gt; e &lt;strong&gt;métodos de execução&lt;/strong&gt; que ajudam a gerenciar tarefas assíncronas de forma eficiente. Esses métodos são ferramentas essenciais para controlar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O tempo de execução das tarefas.&lt;/li&gt;
&lt;li&gt;O contexto em que as tarefas são executadas.&lt;/li&gt;
&lt;li&gt;O início e a sincronização de múltiplas corrotinas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neste artigo, exploraremos os métodos mais importantes, como &lt;code&gt;withTimeout&lt;/code&gt;, &lt;code&gt;withContext&lt;/code&gt;, &lt;code&gt;launch&lt;/code&gt;, &lt;code&gt;async&lt;/code&gt;, e outros, com exemplos práticos para entender como e quando usá-los.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – Métodos Utilitários&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2.1 – withTimeout&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Cancela a execução de um bloco de código se o tempo limite for atingido.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para evitar que tarefas assíncronas fiquem presas indefinidamente.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;withTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Tempo limite de 1 segundo&lt;/span&gt;
            &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula uma tarefa longa&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tarefa concluída!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TimeoutCancellationException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tempo limite atingido! Tarefa cancelada."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2.2 - withTimeoutOrNull&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Semelhante ao &lt;code&gt;withTimeout&lt;/code&gt;, mas em vez de lançar uma exceção, retorna null se o tempo limite for atingido.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para evitar o uso de exceções e lidar com o timeout de forma mais controlada.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;resultado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withTimeoutOrNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Tempo limite de 1 segundo&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Simula uma tarefa longa&lt;/span&gt;
        &lt;span class="s"&gt;"Tarefa concluída!"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tempo limite atingido! Retornou null."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2.3 – withContext&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Altera o contexto da corrotina (ex.: muda o dispatcher).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para trocar o dispatcher de forma temporária dentro de uma corrotina.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando no Dispatcher Padrão: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando no Dispatcher IO: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"De volta ao Dispatcher Padrão: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2.4 – delay&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Suspende a execução de uma corrotina por um período de tempo, sem bloquear a thread.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para simular tarefas demoradas ou esperar por uma resposta.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Iniciando a tarefa..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Suspende por 1 segundo&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tarefa concluída!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2.5 – yield&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Cede o contexto atual, permitindo que outras corrotinas sejam executadas.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para melhorar a cooperação entre corrotinas e evitar bloqueios desnecessários.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Corrotina 1 - Iteração $i"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Cede o contexto&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Corrotina 2 - Iteração $i"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Cede o contexto&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Métodos de Execução&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 – launch&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Cria uma nova corrotina e inicia sua execução imediatamente.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Quando você não precisa retornar um resultado da corrotina.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Corrotina iniciada!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Corrotina finalizada!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.2 – async&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Cria uma nova corrotina que retorna um valor (deferred).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para tarefas assíncronas que retornam resultados. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;resultado&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="s"&gt;"Resultado calculado!"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Esperando o resultado..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Resultado: ${resultado.await()}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.3 – runBlocking&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Executa corrotinas em uma função bloqueante.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Apenas em casos específicos, como scripts pequenos ou para testes rápidos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Iniciando runBlocking"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finalizando runBlocking"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;4 – Comparação: Métodos Utilitários vs. Métodos de Execução&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspecto&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Métodos Utilitários&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Métodos de Execução&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Função principal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Controlar tempo, contexto e suspensão.&lt;/td&gt;
&lt;td&gt;Iniciar e gerenciar corrotinas.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Retorno de valor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Geralmente, não retornam valores.&lt;/td&gt;
&lt;td&gt;Alguns retornam valores (ex.: &lt;code&gt;async&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exemplos principais&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;withTimeout&lt;/code&gt;, &lt;code&gt;delay&lt;/code&gt;, &lt;code&gt;yield&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;launch&lt;/code&gt;, &lt;code&gt;async&lt;/code&gt;, &lt;code&gt;runBlocking&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Os métodos utilitários e de execução são ferramentas indispensáveis no ecossistema de corrotinas do Kotlin. Eles permitem que você controle a execução assíncrona de maneira precisa, escalável e eficiente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resumo dos Métodos:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Utilitários:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Controle de tempo&lt;/strong&gt;: &lt;code&gt;withTimeout&lt;/code&gt;, &lt;code&gt;withTimeoutOrNull&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contexto&lt;/strong&gt;: &lt;code&gt;withContext&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suspensão&lt;/strong&gt;: &lt;code&gt;delay&lt;/code&gt;, &lt;code&gt;yield&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1. Execução:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;launch&lt;/code&gt;&lt;/strong&gt; para corrotinas que não retornam valores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; para corrotinas que retornam resultados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;runBlocking&lt;/code&gt;&lt;/strong&gt; para executar corrotinas em scripts ou testes simples.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No próximo artigo, exploraremos como testar corrotinas e fluxos de maneira eficiente com ferramentas nativas e bibliotecas como o Turbine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referência&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Documentação oficial do Kotlin sobre corrotinas&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>async</category>
      <category>programming</category>
    </item>
    <item>
      <title>Scopes in Kotlin: Controlling Lifecycle and Cancellation of Coroutines</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 27 Feb 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/scopes-in-kotlin-controlling-lifecycle-and-cancellation-of-coroutines-33nl</link>
      <guid>https://dev.to/comunidadedevspace/scopes-in-kotlin-controlling-lifecycle-and-cancellation-of-coroutines-33nl</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Managing the lifecycle of coroutines is one of the most important aspects of asynchronous programming in Kotlin. To this end, Kotlin provides &lt;strong&gt;scopes&lt;/strong&gt;: structures that help you control how and when coroutines run, as well as making it easy to cancel tasks when necessary.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore the main types of scopes in Kotlin and their differences. You'll see how choosing the right scope can simplify managing coroutines in your code.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – What are Scopes?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Scopes in Kotlin are &lt;strong&gt;"managers" of the coroutines lifecycle.&lt;/strong&gt; They:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Determine where and how coroutines will be executed.&lt;/li&gt;
&lt;li&gt;Control the life cycle of coroutines, including their cancellation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Scope Types:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Class-based scopes:&lt;/strong&gt; Used for long-term operations or associated with specific components, such as &lt;code&gt;viewModelScope&lt;/code&gt; in Android.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role-based scopes:&lt;/strong&gt; Used for temporary and local operations, such as &lt;code&gt;coroutineScope&lt;/code&gt; and &lt;code&gt;supervisorScope&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Class-Based Scopes&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 – CoroutineScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
It is the base interface for creating custom scopes. You can associate a &lt;code&gt;CoroutineScope&lt;/code&gt; with a specific context (e.g. a &lt;code&gt;Dispatcher&lt;/code&gt;) to manage coroutines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
To create custom scopes that control the lifecycle of multiple coroutines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;customScope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CoroutineScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;customScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running inside CoroutineScope:${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.2 – viewModelScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
A special scope provided by the &lt;code&gt;Android Jetpack&lt;/code&gt; library, designed for the lifecycle of &lt;code&gt;ViewModels&lt;/code&gt;. When the ViewModel is destroyed, all coroutines associated with the viewModelScope are automatically canceled.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;When to use?&lt;/strong&gt;&lt;br&gt;
To manage UI-associated coroutines on Android.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.ViewModel&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.viewModelScope&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.launch&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyViewModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;loadData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Loading data into thread: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.3 – backgroundScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
A scope designed for long-term operations that can continue even if the life cycle of the main component ends.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;When to use?&lt;/strong&gt;&lt;br&gt;
For tasks that need to persist beyond their immediate lifecycle, such as background sync.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;backgroundScope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CoroutineScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;backgroundScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running in the background:${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;4 – Role-Based Scopes&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4.1 – coroutineScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
A suspend function that creates a temporary scope. All coroutines within a &lt;code&gt;coroutineScope&lt;/code&gt; share the same &lt;code&gt;Job&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
To ensure that all tasks within a block are completed or cancelled together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines&lt;/span&gt; &lt;span class="p"&gt;.*&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;coroutineScope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Coroutine 1 running..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Coroutine 2 running..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"All coroutines completed."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;4.2 – supervisorScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Similar to &lt;code&gt;coroutineScope&lt;/code&gt;, but with one crucial difference: failures in one coroutine &lt;strong&gt;do not affect the others&lt;/strong&gt; within the scope.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
To ensure that all tasks within a block are completed or cancelled together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;supervisorScope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Coroutine 1 running..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error in Coroutine 1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Coroutine 2 running..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SupervisorScope completed."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Comparison: coroutineScope vs. supervisorScope&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Appearance&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;coroutineScope&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;supervisorScope&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cancellation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cancels all coroutines on failure.&lt;/td&gt;
&lt;td&gt;Only the coroutine with the error is canceled.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Relationship between tasks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Coroutines dependent on each other.&lt;/td&gt;
&lt;td&gt;Independent coroutines .&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;When to use&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When all tasks must succeed.&lt;/td&gt;
&lt;td&gt;When tasks can fail independently.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6 – Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Scopes are powerful tools in Kotlin for managing the lifecycle of coroutines. They help prevent resource leaks and make it easier to cancel unnecessary tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Scope Summary:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;CoroutineScope&lt;/strong&gt;: For custom scopes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;viewModelScope&lt;/strong&gt;: To manage coroutines bound to ViewModels in Android.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;coroutineScope&lt;/strong&gt;: For temporary scopes where all tasks depend on each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;supervisorScope&lt;/strong&gt;: For independent tasks.
In the next article, we will explore utility methods and execution methods that you can use to further optimize your coroutines .&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Official Kotlin documentation on coroutines&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>scope</category>
      <category>android</category>
    </item>
    <item>
      <title>Escopos no Kotlin: Controlando Ciclo de Vida e Cancelamento de Corrotinas</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 27 Feb 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/escopos-no-kotlin-controlando-ciclo-de-vida-e-cancelamento-de-corrotinas-142o</link>
      <guid>https://dev.to/comunidadedevspace/escopos-no-kotlin-controlando-ciclo-de-vida-e-cancelamento-de-corrotinas-142o</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Gerenciar o ciclo de vida de corrotinas é um dos aspectos mais importantes da programação assíncrona no Kotlin. Para isso, o Kotlin oferece &lt;strong&gt;escopos&lt;/strong&gt;: estruturas que ajudam a controlar como e quando corrotinas são executadas, além de facilitar o cancelamento de tarefas quando necessário.&lt;/p&gt;

&lt;p&gt;Neste artigo, exploraremos os principais tipos de escopos no Kotlin e suas diferenças. Você verá como escolher o escopo certo pode simplificar o gerenciamento de corrotinas no seu código.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2 – O Que São Escopos?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Escopos no Kotlin são &lt;strong&gt;"gestores" do ciclo de vida das corrotinas.&lt;/strong&gt; Eles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Determinam onde e como as corrotinas serão executadas.&lt;/li&gt;
&lt;li&gt;Controlam o ciclo de vida das corrotinas, incluindo seu cancelamento.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Tipos de Escopos:&lt;/strong&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Escopos baseados em classes:&lt;/strong&gt; Utilizados para operações de longo prazo ou associadas a componentes específicos, como &lt;code&gt;viewModelScope&lt;/code&gt; em Android.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escopos baseados em funções:&lt;/strong&gt; Utilizados para operações temporárias e locais, como &lt;code&gt;coroutineScope&lt;/code&gt; e &lt;code&gt;supervisorScope&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Escopos Baseados em Classes&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 – CoroutineScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
É a interface base para criar escopos personalizados. Você pode associar um &lt;code&gt;CoroutineScope&lt;/code&gt; a um contexto específico (por exemplo, um &lt;code&gt;Dispatcher&lt;/code&gt;) para gerenciar corrotinas.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para criar escopos customizados que controlam o ciclo de vida de várias corrotinas.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;customScope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CoroutineScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;customScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando dentro do CoroutineScope: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.2 – viewModelScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Um escopo especial fornecido pela biblioteca &lt;code&gt;Android Jetpack&lt;/code&gt;, projetado para o ciclo de vida de &lt;code&gt;ViewModels&lt;/code&gt;. Quando o ViewModel é destruído, todas as corrotinas associadas ao viewModelScope são automaticamente canceladas.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quando usar?&lt;/strong&gt;&lt;br&gt;
Para gerenciar corrotinas associadas à UI no Android.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.ViewModel&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.viewModelScope&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.launch&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyViewModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;loadData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Carregando dados na thread: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3.3 – backgroundScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Um escopo projetado para operações de longo prazo que podem continuar mesmo se o ciclo de vida do componente principal terminar.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quando usar?&lt;/strong&gt;&lt;br&gt;
Para tarefas que precisam persistir além do ciclo de vida imediato, como sincronização em segundo plano.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;backgroundScope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CoroutineScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;backgroundScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando no background: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;4 – Escopos Baseados em Funções&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4.1 – coroutineScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Uma função suspensa que cria um escopo temporário. Todas as corrotinas dentro de um &lt;code&gt;coroutineScope&lt;/code&gt; compartilham o mesmo &lt;code&gt;Job&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para garantir que todas as tarefas dentro de um bloco sejam concluídas ou canceladas em conjunto.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;coroutineScope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Corrotina 1 executando..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Corrotina 2 executando..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Todas as corrotinas concluídas."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;4.2 – supervisorScope&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Semelhante ao &lt;code&gt;coroutineScope&lt;/code&gt;, mas com uma diferença crucial: falhas em uma corrotina &lt;strong&gt;não afetam as outras&lt;/strong&gt; dentro do escopo.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para garantir que todas as tarefas dentro de um bloco sejam concluídas ou canceladas em conjunto.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;supervisorScope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Corrotina 1 executando..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro na Corrotina 1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Corrotina 2 executando..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SupervisorScope concluído."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;5 – Comparação: coroutineScope vs. supervisorScope&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspecto&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;coroutineScope&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;supervisorScope&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cancelamento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cancela todas as corrotinas em caso de falha.&lt;/td&gt;
&lt;td&gt;Apenas a corrotina com erro é cancelada.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Relacionamento entre tarefas&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Corrotinas dependentes umas das outras.&lt;/td&gt;
&lt;td&gt;Corrotinas independentes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Quando usar&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Quando todas as tarefas precisam ter sucesso.&lt;/td&gt;
&lt;td&gt;Quando as tarefas podem falhar independentemente.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6 – Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Escopos são ferramentas poderosas no Kotlin para gerenciar o ciclo de vida de corrotinas. Eles ajudam a evitar vazamentos de recursos e facilitam o cancelamento de tarefas desnecessárias.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Resumo dos Escopos:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;CoroutineScope&lt;/strong&gt;: Para escopos personalizados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;viewModelScope&lt;/strong&gt;: Para gerenciar corrotinas vinculadas a ViewModels no Android.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;coroutineScope&lt;/strong&gt;: Para escopos temporários onde todas as tarefas dependem umas das outras.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;supervisorScope&lt;/strong&gt;: Para tarefas independentes.
No próximo artigo, exploraremos os métodos utilitários e métodos de execução que você pode usar para otimizar ainda mais suas corrotinas.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Referência&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Documentação oficial do Kotlin sobre corrotinas&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>scopes</category>
      <category>android</category>
    </item>
    <item>
      <title>Dispatchers e Contextos no Kotlin: Escolhendo o Lugar Certo para Suas Corrotinas</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 20 Feb 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/dispatchers-e-contextos-no-kotlin-escolhendo-o-lugar-certo-para-suas-corrotinas-3nh2</link>
      <guid>https://dev.to/comunidadedevspace/dispatchers-e-contextos-no-kotlin-escolhendo-o-lugar-certo-para-suas-corrotinas-3nh2</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As &lt;strong&gt;corrotinas no Kotlin&lt;/strong&gt; são uma solução moderna para programação assíncrona. Mas para aproveitar todo o potencial delas, é essencial entender como funcionam os &lt;strong&gt;Dispatchers e Contextos&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que são Dispatchers?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Dispatchers definem &lt;strong&gt;onde e como&lt;/strong&gt; as corrotinas serão executadas. Eles permitem que você escolha o ambiente ideal para cada tarefa, seja na &lt;strong&gt;thread principal&lt;/strong&gt;, em um pool de threads para &lt;code&gt;I/O&lt;/code&gt;, ou até mesmo sem vinculação a threads específicas.&lt;/p&gt;

&lt;p&gt;Neste artigo, você aprenderá sobre os principais tipos de Dispatchers e como usá-los para controlar o contexto das suas corrotinas.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;2 – O Que São Dispatchers e Contextos?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;No Kotlin, o &lt;strong&gt;contexto de uma corrotina&lt;/strong&gt; é uma combinação de informações que definem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;O Dispatcher:&lt;/strong&gt; Quem e onde executará a tarefa (ex.: &lt;code&gt;Dispatchers.IO&lt;/code&gt; para leitura de dados).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O Job:&lt;/strong&gt; O gerenciador da corrotina, responsável por controlar seu ciclo de vida (não abordaremos &lt;code&gt;Job&lt;/code&gt; em detalhes aqui).
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O Dispatcher é o componente mais importante para determinar &lt;strong&gt;como a tarefa será executada&lt;/strong&gt;. Ele ajuda a otimizar a performance distribuindo as tarefas corretamente.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Principais Dispatchers&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 – Dispatchers.Main&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O que é?&lt;/strong&gt;
Usado para executar tarefas na &lt;strong&gt;thread principal&lt;/strong&gt;, ideal para interações com a UI.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quando usar?&lt;/strong&gt;
Para atualizações de interface em aplicativos Android ou Desktop.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando na Thread Principal: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3.2 – Dispatchers.IO&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;O que é?&lt;/strong&gt;&lt;br&gt;
Otimizado para tarefas de entrada e saída (Input/Output), como leitura/escrita de arquivos ou chamadas de APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quando usar?&lt;/strong&gt;&lt;br&gt;
Para operações que envolvem leitura ou gravação intensiva de dados.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando no Dispatcher IO: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;3.3 – Dispatchers.Default&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;O que é?&lt;/strong&gt;&lt;br&gt;
Projetado para operações intensivas de CPU, como cálculos complexos ou processamento de dados em massa.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quando usar?&lt;/strong&gt;&lt;br&gt;
Para tarefas que exigem muito poder de processamento.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Executando no Dispatcher Default: ${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4 – Conclusão
&lt;/h2&gt;

&lt;p&gt;Os Dispatchers no Kotlin são ferramentas essenciais para otimizar a execução de tarefas assíncronas. Eles permitem que você escolha o ambiente certo para cada tarefa, garantindo performance e escalabilidade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumo dos Dispatchers:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Dispatchers.Main&lt;/code&gt;&lt;/strong&gt;: Para interações com a UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Dispatchers.IO&lt;/code&gt;&lt;/strong&gt;: Para tarefas de entrada/saída.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Dispatchers.Default&lt;/code&gt;&lt;/strong&gt;: Para cálculos intensivos.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No próximo artigo, exploraremos como os escopos ajudam a gerenciar o ciclo de vida das corrotinas de forma eficiente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referência&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Documentação oficial do Kotlin sobre corrotinas&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>dispatchers</category>
      <category>programming</category>
    </item>
    <item>
      <title>Dispatchers and Contexts in Kotlin: Choosing the Right Place for Your Coroutines</title>
      <dc:creator>Alan Gomes</dc:creator>
      <pubDate>Thu, 20 Feb 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/comunidadedevspace/dispatchers-and-contexts-in-kotlin-choosing-the-right-place-for-your-coroutines-oah</link>
      <guid>https://dev.to/comunidadedevspace/dispatchers-and-contexts-in-kotlin-choosing-the-right-place-for-your-coroutines-oah</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;1 – Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Coroutines in Kotlin&lt;/strong&gt; are a modern solution for asynchronous programming. But to take full advantage of them, it is essential to understand how &lt;strong&gt;Dispatchers and Contexts&lt;/strong&gt; work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are Dispatchers?&lt;/strong&gt;&lt;br&gt;
Dispatchers define &lt;strong&gt;where and how&lt;/strong&gt; coroutines will run. They allow you to choose the ideal environment for each task, whether on the &lt;strong&gt;main thread&lt;/strong&gt;, in a thread pool for &lt;code&gt;I/O&lt;/code&gt;, or even without binding to specific threads.&lt;/p&gt;

&lt;p&gt;In this article, you will learn about the main types of Dispatchers and how to use them to control the context of your coroutines .&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;2 – What are Dispatchers and Contexts?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In Kotlin, a coroutine's &lt;strong&gt;context&lt;/strong&gt; is a combination of information that defines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Dispatcher:&lt;/strong&gt; Who and where will execute the task (e.g. &lt;code&gt;Dispatchers.IO&lt;/code&gt; for reading data).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Job:&lt;/strong&gt; The coroutine manager, responsible for controlling its life cycle (we will not cover &lt;code&gt;Job&lt;/code&gt; in detail here).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Dispatcher is the most important component in determining &lt;strong&gt;how the task will be executed&lt;/strong&gt;. It helps optimize performance by distributing tasks correctly.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;3 – Main Dispatchers&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 – Dispatchers.Main&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
Used to execute tasks on the &lt;strong&gt;main thread&lt;/strong&gt;, ideal for UI interactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use?&lt;/strong&gt;
For interface updates in Android or Desktop applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running in Main Thread: ${ Thread.currentThread ().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3.2 – Dispatchers.IO&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt;&lt;br&gt;
Optimized for input/output tasks, such as reading/writing files or calling APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;When to use?&lt;/strong&gt;&lt;br&gt;
For operations involving intensive reading or writing of data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running in IO Dispatcher:${Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;3.3 – Dispatchers.Default&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt;&lt;br&gt;
Designed for CPU intensive operations such as complex calculations or bulk data processing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;When to use?&lt;/strong&gt;&lt;br&gt;
For tasks that require a lot of processing power.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.*&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runBlocking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running in Dispatcher Default:${ Thread.currentThread().name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4 – Conclusion
&lt;/h2&gt;

&lt;p&gt;Dispatchers in Kotlin are essential tools for optimizing the execution of asynchronous tasks. They allow you to choose the right environment for each task, ensuring performance and scalability .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dispatcher Summary:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Dispatchers.Main&lt;/code&gt;&lt;/strong&gt;: For interactions with the UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Dispatchers.IO&lt;/code&gt;&lt;/strong&gt;: For input/output tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Dispatchers.Default&lt;/code&gt;&lt;/strong&gt;: For intensive computations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the next article, we will explore how scopes help manage the lifecycle of coroutines efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;Official Kotlin documentation on coroutines&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>coroutines</category>
      <category>dispatchers</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
