suspend function: এটি কী, সিনট্যাক্স এবং কোরুটিনে কাজ

লেখক: IT Sectr প্রকাশিত: 2026-06-22 পড়ার সময়: 9 মিনিট

Suspend function হল suspend মডিফায়ার সহ একটি ফাংশন যা থ্রেড ব্লক না করে তার নির্বাহ থামাতে পারে এবং পরে একই কোরুটিনে পুনরায় শুরু করতে পারে। JetBrains Kotlin Docs, 2025 অনুসারে, সাসপেন্ড ফাংশনগুলি কোরুটিনের মৌলিক বিল্ডিং ব্লক, যা কলব্যাক ছাড়াই অ্যাসিঙ্ক্রোনিসিটি প্রদান করে। প্রতিটি সাসপেন্ড ফাংশন Continuation-এর ভিত্তিতে একটি স্টেট মেশিনে কম্পাইল হয়, যা সাসপেনশন পয়েন্টগুলির কার্যকর ব্যবস্থাপনা সক্ষম করে।

মূল পয়েন্ট

  • Suspend — একটি Kotlin কীওয়ার্ড যা ফাংশনকে থামানো যায় (অ্যাসিঙ্ক্রোনাস) হিসেবে চিহ্নিত করে
  • Continuation — একটি লুকানো প্যারামিটার যা কম্পাইলার স্টেট সংরক্ষণের জন্য প্রতিটি সাসপেন্ড ফাংশনে যোগ করে
  • সাসপেনশন পয়েন্ট — যেখানে অন্যান্য সাসপেন্ড ফাংশন কল করা হয়, যেখানে কোরুটিন ব্লক না করে থামতে পারে
  • স্টেট মেশিন — সাসপেন্ড ফাংশনের অভ্যন্তরীণ উপস্থাপনা, যেখানে প্রতিটি সাসপেনশন পয়েন্ট একটি পৃথক স্টেট
  • শুধুমাত্র কোরুটিন থেকে কল — সাসপেন্ড ফাংশন শুধুমাত্র অন্য সাসপেন্ড ফাংশন বা launch/async থেকে কল করা যায়

Kotlin-এ suspend function কী?

Suspend function হল suspend কীওয়ার্ড দিয়ে ঘোষিত একটি ফাংশন যা থ্রেড ব্লক না করে এক বা একাধিক পয়েন্টে নির্বাহ থামাতে পারে। অন্য সাসপেন্ড ফাংশনের ভিতরে সাসপেন্ড ফাংশনের প্রতিটি কল একটি সম্ভাব্য সাসপেনশন পয়েন্ট।

kotlin
suspend fun fetchUserData(): User {
    val response = httpClient.get("/user")
    return parser.parse(response)
}

Kotlin কম্পাইলার এই ধরনের ফাংশনকে স্টেট মেশিনে রূপান্তর করে। প্রতিটি সাসপেনশন পয়েন্ট (অন্য সাসপেন্ড ফাংশনের কল) একটি স্টেট (label) হয়ে যায়। বর্তমান থ্রেড স্টেটগুলির মধ্যে মুক্তি পায়, এবং অপেক্ষিত অপারেশন শেষ হওয়ার পরে, নির্বাহ পরবর্তী স্টেট থেকে পুনরায় শুরু হয়।

ইতিহাস

সাসপেন্ড ফাংশন Kotlin 1.3 (2018) এ কোরুটিনের সাথে একটি পরীক্ষামূলক বৈশিষ্ট্য হিসাবে আবির্ভূত হয় এবং Kotlin 1.5 (2021) এ স্থিতিশীল হয়। এর আগে, Kotlin/Java-এ অ্যাসিঙ্ক্রোনিসিটি কলব্যাক, RxJava এবং CompletableFuture-এর মাধ্যমে অর্জিত হত। সাসপেন্ড ফাংশন রৈখিক সিনট্যাক্স এবং স্বয়ংক্রিয় থ্রেড ব্যবস্থাপনার সাথে একটি বিকল্প প্রস্তাব করেছিল।

সাসপেন্ড ফাংশন কীভাবে কাজ করে: Continuation এবং স্টেট মেশিন

সাসপেন্ড ফাংশনের অভ্যন্তরীণ কার্যপ্রণালী বোঝা কোরুটিনের সাথে সঠিকভাবে কাজ করার চাবিকাঠি। সাধারণ ফাংশনের বিপরীতে, প্রতিটি সাসপেন্ড ফাংশন Continuation ইন্টারফেস সহ একটি ক্লাসে কম্পাইল হয়।

Continuation — লুকানো প্যারামিটার

Kotlin কম্পাইলার প্রতিটি সাসপেন্ড ফাংশনের প্যারামিটার তালিকার শেষে Continuation টাইপের একটি প্যারামিটার যোগ করে। Continuation-এর মধ্যে রয়েছে:

  • context — CoroutineContext (ডিসপ্যাচার, job, প্রসঙ্গ উপাদান)
  • resumeWith — ফলাফল বা ব্যতিক্রম সহ নির্বাহ পুনরায় শুরু করার পদ্ধতি
  • label — স্টেট মেশিনে বর্তমান স্টেটের সূচক

স্টেট মেশিনের উদাহরণ

ধরুন আমাদের কাছে দুটি অন্যান্য সাসপেন্ড ফাংশনের কল সহ একটি সাসপেন্ড ফাংশন আছে:

kotlin
suspend fun process() {
    val a = stepOne()
    val b = stepTwo(a)
    println(b)
}

কম্পাইলার এটিকে লেবেল সহ একটি স্টেট মেশিনে রূপান্তর করে:

kotlin
// Simplified generated code representation
fun process(cont: Continuation<Unit>): Any? {
    val cont = cont as ProcessContinuation
    when (cont.label) {
        0 -> {
            cont.label = 1
            if (stepOne(cont) == COROUTINE_SUSPENDED) return COROUTINE_SUSPENDED
        }
        1 -> {
            cont.label = 2
            val a = cont.result as TypeA
            if (stepTwo(a, cont) == COROUTINE_SUSPENDED) return COROUTINE_SUSPENDED
        }
        2 -> {
            println(cont.result)
            Unit
        }
    }
}

মূল পর্যবেক্ষণ: যদি ফাংশন COROUTINE_SUSPENDED ফেরত দেয়, বর্তমান থ্রেড মুক্তি পায়। যখন অ্যাসিঙ্ক্রোনাস অপারেশন শেষ হয়, Continuation.resumeWith কল করা হয়, এবং স্টেট মেশিন পরবর্তী লেবেল থেকে অব্যাহত থাকে।

সাসপেন্ড ফাংশনের সিনট্যাক্স: ঘোষণা এবং আহ্বান

সাসপেন্ড ফাংশন ঘোষণা করা সাধারণ ফাংশন থেকে আলাদা নয়, শুধু fun-এর আগে suspend কীওয়ার্ড ছাড়া। শুধুমাত্র একটি সীমাবদ্ধতা আছে: সাসপেন্ড ফাংশন শুধুমাত্র কোরুটিন বা অন্য সাসপেন্ড ফাংশন থেকে কল করা যায়।

মৌলিক ঘোষণা

kotlin
suspend fun delayAndReturn(ms: Long): String {
    delay(ms)
    return "Done after ${ms}ms"
}

এই উদাহরণে, delay একটি সাসপেন্ড ফাংশন যা থ্রেড ব্লক না করে নির্দিষ্ট মিলিসেকেন্ডের জন্য কোরুটিন থামায়। বিলম্বের পরে, নির্বাহ পুনরায় শুরু হয়।

কোরুটিন থেকে কল করা

kotlin
fun main() = runBlocking {
    val result = delayAndReturn(1000)
    println(result)
}

runBlocking সাধারণ জগৎ এবং কোরুটিনের মধ্যে একটি সেতু তৈরি করে। lambda-এর ভিতরে, যেকোনো সাসপেন্ড ফাংশন কল করা যেতে পারে।

সাসপেন্ড ল্যাম্বডা এবং কার্যকরী টাইপ

Kotlin কার্যকরী টাইপের সাসপেন্ড সংস্করণ সমর্থন করে — suspend () -> T এবং suspend (A) -> B. এটি উচ্চ-ক্রমের ফাংশনে অ্যাসিঙ্ক্রোনাস ল্যাম্বডা পাস করার অনুমতি দেয়:

kotlin
suspend fun  withRetry(
    retries: Int = 3,
    block: suspend () -> T
): T {
    repeat(retries - 1) {
        try { return block() }
        catch (_: Exception) { delay(100) }
    }
    return block()
}

withRetry ফাংশন একটি সাসপেন্ড ল্যাম্বডা নেয় এবং ত্রুটিতে এর নির্বাহ পুনরায় চেষ্টা করে। এটি পুনরায় চেষ্টা সহ নেটওয়ার্ক অনুরোধের জন্য একটি সাধারণ প্যাটার্ন।

সাসপেন্ড ফাংশন সাধারণ ফাংশন থেকে কীভাবে আলাদা

সাসপেন্ড এবং সাধারণ ফাংশনের মধ্যে পার্থক্য শুধু একটি মডিফায়ার যোগ করার বাইরে যায়। আসুন মূল পার্থক্যগুলি দেখি।

বৈশিষ্ট্যসাধারণ ফাংশনসাসপেন্ড ফাংশন
নির্বাহ থ্রেডশেষ পর্যন্ত থ্রেড ব্লক করেথ্রেড ছেড়ে দিতে পারে এবং পরে পুনরায় শুরু করতে পারে
কম্পাইলার প্যারামিটারশুধুমাত্র নির্দিষ্ট প্যারামিটারশেষে অন্তর্নিহিত Continuation
সাধারণ ফাংশন থেকে কলহ্যাঁনা
স্ট্যাকভৌত থ্রেড স্ট্যাকহিপে স্টেট মেশিন + পয়েন্টগুলির মধ্যে ভৌত স্ট্যাক
রিটার্ন মানসরাসরি মানমান বা COROUTINE_SUSPENDED
কর্মক্ষমতাসর্বনিম্ন ওভারহেড~প্রতি স্টেট মেশিনে কয়েক ন্যানোসেকেন্ড (Kotlin 1.9+)

কেন সাসপেন্ড ফাংশন সাধারণ ফাংশন থেকে কল করা যায় না

সাধারণ ফাংশনে Continuation নেই — তার স্টেট সংরক্ষণের জায়গা নেই এবং নির্বাহ পুনরায় শুরু করার মতো কিছুই নেই। যদি আপনার সাধারণ ফাংশন থেকে সাসপেন্ড ফাংশন কল করার প্রয়োজন হয়, তাহলে runBlocking (পরীক্ষার জন্য) বা CoroutineScope.launch (জীবনচক্র সচেতনতা সহ উৎপাদনের জন্য) ব্যবহার করুন।

Android-এ সাসপেন্ড ফাংশনের উদাহরণ

আসুন Kotlin দিয়ে Android অ্যাপে সাসপেন্ড ফাংশন ব্যবহারের তিনটি বাস্তব দৃশ্য দেখি।

উদাহরণ 1: সাসপেন্ড কোয়েরি সহ Room DAO

Room সরাসরি সাসপেন্ড ফাংশন সমর্থন করে — কোয়েরি স্বয়ংক্রিয়ভাবে পটভূমি থ্রেডে নির্বাহিত হয়:

kotlin
@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE id = :id")
    suspend fun getUser(id: Int): User?

    @Insert
    suspend fun insertUser(user: User)
}

Room অভ্যন্তরীণভাবে কোয়েরি নির্বাহের জন্য Dispatchers.IO ব্যবহার করে, এবং ফলাফল সেই ডিসপ্যাচারে ফেরত দেওয়া হয় যেখানে সাসপেন্ড ফাংশন কল করা হয়েছিল।

উদাহরণ 2: স্ক্রিন লোডিংয়ের জন্য সাসপেন্ড ফাংশনের কম্পোজিশন

kotlin
class ProfileViewModel : ViewModel() {
    private val repo = ProfileRepository()

    fun loadProfile(id: String) {
        viewModelScope.launch {
            val profile = repo.getProfile(id)
            _profile.value = profile
        }
    }
}

ViewModelScope.launch একটি কোরুটিন তৈরি করে, যার ভিতরে getProfile সাসপেন্ড ফাংশন কল করা হয়। ফলাফল পাওয়ার পরে, UI প্রধান থ্রেডে আপডেট হয়।

উদাহরণ 3: অনুক্রমিক অ্যাসিঙ্ক্রোনাস ধাপ

kotlin
suspend fun placeOrder(cart: Cart): OrderResult {
    val validated = validateCart(cart)
    val payment = processPayment(validated)
    val receipt = sendReceipt(payment)
    return receipt
}

তিনটি সাসপেন্ড ফাংশন ক্রমানুসারে নির্বাহিত হয়। প্রতিটি ধাপে, কোরুটিন থ্রেড ব্লক না করে থামতে পারে। যদি কোনো ধাপ ব্যতিক্রম নিক্ষেপ করে, বাকি ধাপগুলি নির্বাহিত হয় না, যা ভুল অর্ডার অবস্থা থেকে রক্ষা করে।

সাসপেন্ড ফাংশন নিয়ে কাজ করার সময় সাধারণ ভুল

অভিজ্ঞ Kotlin ডেভেলপাররাও সাসপেন্ড ফাংশন ডিজাইন করার সময় ভুল করে। আসুন সবচেয়ে সাধারণ ভুলগুলো দেখি।

ভুল 1: সাসপেন্ডের ভিতরে ব্লকিং কল

সাসপেন্ড ফাংশন কোডকে স্বয়ংক্রিয়ভাবে অ্যাসিঙ্ক্রোনাস করে না। Thread.sleep(), InputStream.read() এবং অন্যান্য ব্লকিং কল এখনও থ্রেড ব্লক করবে। ব্লকিং অপারেশন মোড়ানোর জন্য withContext(Dispatchers.IO) ব্যবহার করুন।

ভুল 2: প্রয়োজন ছাড়াই সাসপেন্ড ফাংশন তৈরি করা

যদি একটি ফাংশন অন্য সাসপেন্ড ফাংশন কল না করে এবং অ্যাসিঙ্ক্রোনাস অপারেশন না করে — তাহলে সাসপেন্ড মডিফায়ার অপ্রয়োজনীয়। এটি স্টেট মেশিনের জন্য ওভারহেড যোগ করে এবং কলিং প্রসঙ্গ সীমাবদ্ধ করে। ফাংশনকে তখনই সাসপেন্ড বানান যখন এটি সত্যিই থামে

ভুল 3: CancellationException উপেক্ষা করা

যখন কোরুটিন বাতিল হয়, সাসপেন্ড ফাংশন CancellationException নিক্ষেপ করে। এটি চিন্তা না করে ধরা দেবেন না — আপনি কলিং কোডকে সঠিকভাবে বাতিলকরণ সম্পূর্ণ করার ক্ষমতা থেকে বঞ্চিত করছেন। যদি আপনার চূড়ান্তকরণ অপারেশন করার প্রয়োজন হয়, তাহলে finally ব্লক এবং NonCancellable ব্যবহার করুন।

kotlin
suspend fun safeOperation() {
    try {
        doWork()
    } finally {
        withContext(NonCancellable) {
            cleanup()
        }
    }
}

finally ব্লক সর্বদা নির্বাহিত হয়, বাতিলকরণেও, এবং NonCancellable নিশ্চিত করে যে পরিষ্কারকরণ ব্যাহত না হয়।

ভুল 4: কলব্যাক থেকে সাসপেন্ড ফাংশন কল করা

আপনি কোরুটিন তৈরি না করে সরাসরি কলব্যাক থেকে সাসপেন্ড ফাংশন কল করতে পারবেন না। কলব্যাক শৈলীকে কোরুটিনের সাথে খাপ খাওয়াতে suspendCoroutine বা suspendCancellableCoroutine ব্যবহার করুন।

সচরাচর জিজ্ঞাসিত প্রশ্ন

একটি সাসপেন্ড ফাংশনে কি কোনো সাসপেনশন পয়েন্ট নাও থাকতে পারে?

হ্যাঁ, প্রযুক্তিগতভাবে একটি সাসপেন্ড ফাংশন অন্যান্য সাসপেন্ড ফাংশন কল নাও করতে পারে। কম্পাইলার একটি একক স্টেট (label 0) সহ একটি স্টেট মেশিন তৈরি করবে। তবে, এই ধরনের ফাংশনের কোনো ব্যবহারিক সুবিধা নেই — এটি সাধারণ ফাংশনের মতো চলে কিন্তু ওভারহেড সহ। প্রয়োজন ছাড়া সাসপেন্ড ব্যবহার করবেন না।

সাসপেন্ড ফাংশন ডিবাগ কিভাবে করবেন?

Kotlin kotlinx-coroutines-debug প্রদান করে — DebugProbes এবং কোরুটিন ট্রেসিং টুল সহ একটি লাইব্রেরি। Android Studio-তে Arctic Fox থেকে, ডিবাগারে একটি অন্তর্নির্মিত Coroutines ট্যাব রয়েছে যা সক্রিয় কোরুটিন, তাদের অবস্থা এবং সাসপেনশন পয়েন্ট দেখায়।

সাসপেনশন পয়েন্টের সংখ্যা কি কর্মক্ষমতা প্রভাবিত করে?

প্রতিটি সাসপেনশন পয়েন্ট স্টেট মেশিনে একটি নতুন স্টেট তৈরি করে। অধিকাংশ অ্যাপ্লিকেশনের জন্য, একটি পয়েন্টের ওভারহেড কয়েক ন্যানোসেকেন্ড (Kotlin 1.9+)। শুধুমাত্র লুপে দশ হাজার পয়েন্টের সাথে আপনার অপারেশন একত্রিত করা বা sequence/flow ব্যবহার করার কথা বিবেচনা করা উচিত।

সাসপেন্ড ফাংশন অন্যান্য ভাষায় async/await থেকে কীভাবে আলাদা?

Kotlin-এ, suspend একটি ফাংশন টাইপ মডিফায়ার, রিটার্ন মান মার্কার নয় (যেমন C#-এ async)। যেকোনো সাসপেন্ড ফাংশনের যেকোনো প্যারামিটার এবং রিটার্ন টাইপ থাকতে পারে, এবং এর কল সিনট্যাক্টিকভাবে সাধারণ ফাংশন কল থেকে আলাদা নয় — কল সাইটে কোনো await অপারেটর নেই।

কীভাবে একটি কলব্যাক ফাংশনকে সাসপেন্ডে রূপান্তর করবেন?

অভিযোজনের জন্য suspendCancellableCoroutine ব্যবহার করুন। ভিতরে, আপনি একটি কলব্যাক নিবন্ধন করেন যা continuation.resume() কল করে, এবং যদি কলব্যাক সাবস্ক্রিপশন বাতিল সমর্থন করে তবে একটি বাতিলকরণ টোকেন ফেরত দেন। এটি পুরানো Android API মোড়ানোর মানক প্যাটার্ন।

সারাংশ

  • Suspend function — সাসপেন্ড মডিফায়ার সহ ফাংশন যা Continuation প্রক্রিয়ার মাধ্যমে থ্রেড ব্লক না করে নির্বাহ থামাতে পারে
  • স্টেট মেশিন — Kotlin বাইটকোডে সাসপেন্ড ফাংশনের অভ্যন্তরীণ উপস্থাপনা, যেখানে প্রতিটি সাসপেনশন পয়েন্ট একটি লেবেল সহ একটি পৃথক স্টেট
  • Continuation — একটি লুকানো প্যারামিটার যাতে কোরুটিন প্রসঙ্গ এবং নির্বাহ পুনরায় শুরু করার জন্য resumeWith পদ্ধতি রয়েছে
  • শুধুমাত্র কোরুটিন থেকে কল — সাসপেন্ড ফাংশন runBlocking বা CoroutineScope ছাড়া সাধারণ ফাংশন থেকে অ্যাক্সেসযোগ্য নয়
  • ব্লকিং অপারেশন সাসপেন্ডের ভিতরে withContext(Dispatchers.IO) প্রয়োজন — অন্যথায় থ্রেড ব্লক হয়
  • Room এবং Retrofit স্থানীয়ভাবে সাসপেন্ড ফাংশন সমর্থন করে, স্বয়ংক্রিয়ভাবে পটভূমি থ্রেড পরিচালনা করে
  • CancellationException — finally + NonCancellable-এর মাধ্যমে বাতিলকরণ পরিচালনা করুন, CancellationException চিন্তা না করে ধরা দেবেন না

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন