launch — ماهیت، راه‌اندازی کروتین‌های fire-and-forget و نحوه کار

نویسنده: IT Sectr منتشر شده: 2026-06-22 زمان مطالعه: 7 دقیقه

launch — Coroutine Builder در Kotlin است که کروتین را بدون بازگرداندن نتیجه راه‌اندازی می‌کند و شیء Job را برای مدیریت اجرا بازمی‌گرداند. این builder الگوی fire-and-forget را پیاده‌سازی می‌کند: کروتین کار خود را در نخ پس‌زمینه آغاز می‌کند و به طور خودکار پایان می‌یابد. به گفته مستندات JetBrains، 2024، launch روش اصلی راه‌اندازی وظایف موازی در Kotlin Coroutines است.

نکات کلیدی

  • launch — builder برای راه‌اندازی کروتین‌ها بدون بازگرداندن نتیجه (fire-and-forget)
  • Job — شیء مدیریت کروتین با متدهای cancel()، join()، isActive
  • launch با CoroutineScope برای لغو خودکار کروتین‌های فرزند یکپارچه می‌شود
  • CoroutineStart.LAZY امکان به تأخیر انداختن راه‌اندازی تا فراخوانی صریح start() یا join() را می‌دهد
  • launch در Android برای ذخیره در پایگاه داده، فراخوانی‌های شبکه و به‌روزرسانی UI استفاده می‌شود

launch در Kotlin Coroutines چیست؟

launch — یک تابع توسعه‌دهنده Kotlin است که از طریق import kotlinx.coroutines در دسترس بوده و یک کروتین جدید در CoroutineScope مشخص شده ایجاد می‌کند. برخلاف توابع معمولی، کد داخل launch به صورت همروند اجرا می‌شود — کروتین می‌تواند بدون مسدود کردن نخ معلق (suspend) شده و بعداً از سر گرفته شود.

Builder launch بلوک ساختمانی اساسی مدل کروتین Kotlin است. این builder مقدار محاسبه‌شده را بازنمی‌گرداند، اما شیء Job را بازمی‌گرداند که امکان کنترل اجرای کروتین را فراهم می‌کند. تمام کروتین‌های فرزندی که از طریق launch در داخل کروتین دیگری راه‌اندازی می‌شوند، به والد متصل می‌شوند.

نحو و پارامترهای launch

Builder launch به عنوان یک تابع inline با چند پارامتر تعریف می‌شود: CoroutineScope، CoroutineContext، CoroutineStart و suspend-block. پارامترها مقادیر پیش‌فرض دارند که launch را برای سناریوهای معمولی راحت می‌سازد.

kotlin
public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job

پارامتر context CoroutineContext را می‌پذیرد که توزیع‌کننده، مدیریت‌کننده استثنا و عنصر نام‌گذاری شده را ترکیب می‌کند. بیشتر اوقات Dispatchers.IO، Dispatchers.Main یا SupervisorJob برای جداسازی خطاها ارسال می‌شود.

Job و مدیریت چرخه حیات

Job — شیء برگشتی است که چرخه حیات کروتین را نشان می‌دهد. Job می‌تواند در حالت‌های زیر باشد: New، Active، Completing، Completed، Cancelling، Cancelled. هر حالت وضعیت اجرا را منعکس کرده و امکان واکنش به تغییرات را فراهم می‌کند.

kotlin
val job = CoroutineScope(Dispatchers.IO).launch {
    repeat(10) { i ->
        delay(1000L)
        println("پیشرفت: $i")
    }
}

println("Job فعال است: ${job.isActive}")
delay(2500L)
job.cancel()
println("Job لغو شده است: ${job.isCancelled}")

Job از سلسله‌مراتب پشتیبانی می‌کند: اگر کروتین والد لغو شود، تمام کروتین‌های فرزند به طور خودکار لغو می‌شوند. SupervisorJob این رفتار را تغییر می‌دهد — کروتین‌های فرزند با خطای یکی از آنها لغو نمی‌شوند.

همروندی ساختاریافته در launch

همروندی ساختاریافته به این معناست که هر کروتین در یک CoroutineScope مشخص راه‌اندازی می‌شود و scope تا زمانی که تمام کروتین‌های فرزند کار خود را تمام نکنند، پایان نمی‌پذیرد. launch به طور کامل از این اصل پشتیبانی می‌کند — کروتین‌هایی که در داخل کروتین دیگری راه‌اندازی می‌شوند، فرزندان آن هستند.

فراخوانی‌های تودرتوی launch

در راه‌اندازی تودرتوی launch، یک درخت از کروتین‌ها تشکیل می‌شود. کروتین والد منتظر تکمیل تمام فرزندان می‌ماند که ترتیب اجرای قابل پیش‌بینی را تضمین کرده و مدیریت منابع را ساده می‌کند.

kotlin
fun main() = runBlocking {
    launch {
        launch {
            delay(1000L)
            println("فرزند 1 تکمیل شد")
        }
        launch {
            delay(500L)
            println("فرزند 2 تکمیل شد")
        }
        println("همه فرزندان قبل از این خط تکمیل شدند")
    }
}

این رفتار با همروندی مبتنی بر نخ متفاوت است، جایی که نخ‌های فرزند به والد متصل نیستند. در کروتین‌ها، والد پایان نمی‌یابد تا زمانی که همه فرزندان کار خود را تمام کنند.

مدیریت استثناها در launch

مدیریت استثناها در launch به نوع Job بستگی دارد. برای Job معمولی، استثناها به کروتین والد منتشر شده و آن را لغو می‌کنند. برای SupervisorJob یا SupervisorScope، استثناها جداسازی می‌شوند — خطای یک کروتین فرزند بر سایرین تأثیر نمی‌گذارد.

kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
    try {
        riskyOperation()
    } catch (e: Exception) {
        println("گرفته شد: ${e.message}")
    }
}
scope.launch {
    println("این هنوز به لطف SupervisorJob اجرا می‌شود")
}

برای مدیریت سراسری استثناهای مدیریت‌نشده از CoroutineExceptionHandler استفاده می‌شود. این handler استثناهایی را که در داخل کروتین مدیریت نشده‌اند، گرفته و امکان ثبت خطا بدون کرش برنامه را فراهم می‌کند.

نمونه‌های استفاده از launch در Android

در Android، launch به طور گسترده از ViewModel تا WorkManager استفاده می‌شود. الگوی اصلی استفاده از lifecycleScope در Fragment و viewModelScope در ViewModel برای لغو خودکار کروتین‌ها هنگام پایان چرخه حیات کامپوننت است.

kotlin
class ProfileViewModel : ViewModel() {
    private val repository = UserRepository()

    fun loadProfile(userId: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val profile = repository.fetchProfile(userId)
            withContext(Dispatchers.Main) {
                _profileState.update { it.copy(profile = profile) }
            }
        }
    }
}

viewModelScope به طور خودکار کروتین‌ها را هنگام نابودی ViewModel لغو می‌کند. این کار نشت حافظه را حذف کرده و تضمین می‌کند که عملیات‌های پس‌زمینه پس از از دست رفتن زمینه ادامه نمی‌یابند. علاوه بر این، می‌توان از withContext برای جابجایی بین توزیع‌کننده‌ها استفاده کرد.

سوالات متداول

تفاوت launch با async در Kotlin Coroutines چیست؟

launch Job بازمی‌گرداند و نتیجه اجرا را بازنمی‌گرداند، در حالی که async برای دریافت نتیجه، Deferred<T> بازمی‌گرداند. launch برای عملیات‌های fire-and-forget استفاده می‌شود، async زمانی که باید منتظر بمانید و از مقدار بازگشتی استفاده کنید.

چگونه کروتین راه‌اندازی شده با launch را لغو کنیم؟

روی شیء Job ذخیره شده job.cancel() را فراخوانی کنید. برای لغو گروهی، کل CoroutineScope را از طریق scope.cancel() لغو کنید. کروتین باید همکاری‌کننده باشد — isActive را بررسی کند یا از توابع suspend قابل بررسی استفاده کند.

اگر launch استثنا پرتاب کرد چه باید کرد؟

در داخل بلوک launch از try-catch استفاده کنید یا CoroutineExceptionHandler را در CoroutineContext قرار دهید. برای جداسازی خطاها از SupervisorJob استفاده کنید — در این صورت استثنا در یک کروتین فرزند، بقیه را لغو نمی‌کند.

آیا می‌توان launch را بدون CoroutineScope راه‌اندازی کرد؟

خیر، launch یک تابع توسعه‌دهنده CoroutineScope است. بدون scope، کروتین نمی‌تواند از اصل همروندی ساختاریافته پیروی کند. از GlobalScope.launch با احتیاط استفاده کنید — این کار یک کروتین بدون اتصال به چرخه حیات ایجاد می‌کند.

چند کروتین launch را می‌توان همزمان راه‌اندازی کرد؟

تعداد محدود به پool نخ‌های توزیع‌کننده است. Dispatchers.Default از تعداد نخ‌هایی برابر با تعداد هسته‌های CPU استفاده می‌کند. Dispatchers.IO تا ۶۴ نخ را پشتیبانی می‌کند. هنگام راه‌اندازی تعداد بیشتری کروتین، آنها در صف قرار می‌گیرند.

خلاصه

  • launch — builder اصلی برای کروتین‌های fire-and-forget که شیء Job بازمی‌گرداند
  • Job متدهای مدیریتی را ارائه می‌دهد: cancel()، join()، isActive، isCancelled، isCompleted
  • همروندی ساختاریافته لغو کروتین‌های فرزند را هنگام لغو والد تضمین می‌کند
  • مدیریت استثناها به نوع Job بستگی دارد: معمولی خطاها را منتشر می‌کند، SupervisorJob جداسازی می‌کند
  • lifecycleScope و viewModelScope — راه‌حل‌های آماده برای راه‌اندازی launch در Android
  • CoroutineStart.LAZY راه‌اندازی را تا فراخوانی صریح start() یا join() به تأخیر می‌اندازد
  • launch در Android برای درخواست‌های شبکه، نوشتن در پایگاه داده، تحلیل و کش استفاده می‌شود

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید