Fonctions suspend en Kotlin : ce que c'est et comment les utiliser en 2025

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Que se cache-t-il derrière le mot-clé suspend en Kotlin ?

\n\n

Si vous avez déjà écrit en Kotlin et essayé d'appeler une fonction marquée du modificateur suspend, mais sans coroutine — vous avez très probablement obtenu une erreur de compilation. Et ce n'est pas un bug, c'est une fonctionnalité. Les fonctions suspend sont la base de la programmation asynchrone en Kotlin. En 2025, elles sont devenues encore plus pratiques, mais les questions des débutants (et même des développeurs expérimentés) n'ont pas disparu. L'une des plus populaires sur Stack Overflow — « What does a suspend function mean in Kotlin coroutines? » — a accumulé des milliers de vues. Comprenons cela une fois pour toutes.

\n\n

Une fonction suspend — pas de la magie, mais un contrat

\n\n

Imaginez que vous commandez une pizza. Vous appelez le restaurant, passez commande, et au lieu d'attendre au téléphone 20 minutes, vous continuez vos occupations. Quand la pizza est prête, on vous rappelle — vous « revenez » à la conversation. C'est exactement ce qu'est une fonction suspend : elle peut suspendre son exécution sans bloquer le thread, puis reprendre lorsque le résultat est disponible.

\n\n

Techniquement, suspend n'est pas un mot-clé qui rend une fonction asynchrone « de nulle part ». C'est un contrat : la fonction peut se suspendre, mais n'y est pas obligée. Le compilateur Kotlin transforme une telle fonction en machine à états qui sait sauvegarder et restaurer son état.

\n\n

À quoi ressemble une fonction suspend dans le code ?

\n\n

Voici un exemple très simple :

\n\n
suspend fun fetchUserData(userId: String): User {\n    delay(1000) // simulation d'une requête réseau\n    return User(userId, "Alexei")\n}
\n\n

Vous ne pouvez pas appeler fetchUserData simplement, en dehors d'une coroutine :

\n\n
// Erreur de compilation !\nfun main() {\n    val user = fetchUserData("123") // Suspend function 'fetchUserData' should be called only from a coroutine or another suspend function\n}
\n\n

Pour l'appeler, vous devez être à l'intérieur d'une coroutine. Par exemple :

\n\n
fun main() = runBlocking {\n    val user = fetchUserData("123")\n    println(user.name) // Alexei\n}
\n\n

runBlocking est un pont entre le monde normal et le monde des coroutines. Dans les projets réels, vous ne l'utiliserez presque jamais en production (sauf pour les tests et le main). À la place, vous lancerez des coroutines via CoroutineScope.

\n\n

Que se passe-t-il « sous le capot » ?

\n\n

Lorsque le compilateur voit suspend, il génère un paramètre supplémentaire — un objet Continuation. Cet objet stocke le point où la coroutine a été suspendue, ainsi que toutes les variables locales. Grâce à cela, la coroutine peut « s'endormir » dans un thread et « se réveiller » dans un autre — sans blocage.

\n\n

Important : une fonction suspend ne bloque pas le thread. Pendant qu'elle « dort » (par exemple, en attendant une réponse du serveur), le thread peut exécuter d'autres tâches. C'est la différence clé avec les anciennes approches (Thread.sleep, callback hell).

\n\n

Meilleures pratiques pour l'utilisation des fonctions suspend en 2025

\n\n

Ces dernières années, l'écosystème Kotlin a beaucoup grandi. De nouvelles bibliothèques sont apparues, le compilateur et l'IDE se sont améliorés. Voici ce qu'il faut savoir et appliquer dès maintenant.

\n\n

1. Ne créez pas de fonctions suspend qui ne se suspendent pas

\n\n

Si une fonction ne contient pas d'appels à d'autres fonctions suspend (par exemple, delay, withContext, appel API via Ktor/Retrofit), ne lui mettez pas suspend. Cela induit en erreur et ajoute une surcharge inutile.

\n\n
// Mauvais\nsuspend fun formatName(first: String, last: String): String {\n    return "$first $last".trim()\n}\n\n// Bon\nfun formatName(first: String, last: String): String {\n    return "$first $last".trim()\n}
\n\n

2. Utilisez withContext pour changer de dispatcher

\n\n

Si vous devez effectuer une opération bloquante (lecture de fichier, travail avec une base de données), ne marquez pas la fonction comme suspend et ne la rendez pas

Blogs

Book Recommendations