قبل از خواندن این مقاله این دو مقاله رو بخونید :
این دستور این معنی رو میده ، کوروتینی که در حال حاضر در حال اجرا هست رو suspend کن تا job ای که join شده کامل بشه ، به مثال زیر دقت کنید :
در این مثال ما درون یک کوروتین یک job رو اجرا کردیم ، دستور join در اینجا این کار رو میکنه : تا وقتی job کامل نشده دستورات بعدی اون کوروتین رو اجرا نکن ، پس خروجی به این شکل میشه :
اگه job رو join نکنیم :
زمانی شما به این نیاز دارید که job رو لغو کنید (به هر دلیلی مثلا زیاد طول کشیده یا ...) ، برای این کار از دستور cancel استفاده میشه :
اما کد بالا میتونه بهتر باشه ، قبل از بهینه کردنش به این مثال دقت کنید :
به نظر شما خروجی چیه ؟ قبل از دیدن عکس پایین کمی فکر کنید :
میبینیم که طبق خروجی job به صورت cancelled در نظر گرفته شده و active هم نیست اما این طور در نظر گرفته شده که completed هم نشده ! اگر قبل از لاگ مربوط به isCompleted یک delay بذارید میبینید که به صورت true در میاد ، ما این رو نمیخوایم ! ما میخوایم وقتی job رو cancel میکنیم در قسمت های بعدی اون job به صورت completed در اومده باشه ، پس میآییم cancel رو با join ادغام میکنیم :
در کد بالا کوروتین تا موقعی که job کامل نشده باشه suspend میشه ، میشه این کد رو به این صورت هم نوشت :
نکته : میتونید دستور launch رو به تنهایی درون یک کوروتین اجرا کنید ، یعنی به جای اینکه job رو به صورتهای بالا اجرا کنید صرفا جلوش launch بنویسید (به جای CoroutineScope(Main).launch )
کار این تابع به طور خلاصه اینطوره که اگه شما اونو فراخونی کنید میاد اون Thread یا دسته Thread ای رو از کوروتینی که دارید درش عملیلات انجام میدید میگیره و به کوروتینهای دیگه میده ، با مثال این مبحث رو توضیح میدیم :
به خاطر اینکه در مثال بالا ما فقط در یک Thread کار انجام میدیم (یادآوری اینکه وقتی IO یا Default بگذاریم در چندین Thread کار رو انجام میده ولی Main فقط یک Thread هست) چون job2 در مرحله دوم اجرا شده پس Log هاشم بعد از اتمام Log های job نوشته میشن حالا اونو به این صورت در بیاریم :
اگر این کد رو اجرا کنید در Log هاتون میبینید که Log های مربوط به job بعد از job2 اجرا میشن ، حالا اگه yield رو توی job2 صدا کنیم چی میشه ؟ هیچ فرقی با حالت اول ایجاد نمیشه چون در job2 در حالت معمولی بعد از job مقادیر رو برای ما چاپ میکرد ، حالا اگه به جای Main از IO استفاده کنید و yield رو هم در job بذارید شانس هایی که برای چاپ کردن job2 دارید از job بیشتر میشه و با اینکه به موازات Log ها رو چاپ میکنند اما میبینیم که در انتها دستهی زیادی از Log های مربوط به job آخرِ سر چاپ میشن . میتونیم با cancel ترکیبش کنیم :
میبینیم که Log ها کامل چاپ میشن و بعد تازه کار cancel میشه اما با yield :
بیاییم مثال IO رو هم ببینیم :
و بعد با yield :
دلیل اینکه تعداد بیشتری نسبت به حالت Main چاپ شده اینه که در IO از چندین Thread استفاده میشه ، پس وقتی ما yeild رو صدا بزنیم ممکنه این وسط ها به دلیل متعدد بودن Thread ها فرصتی برای خود Log ها برای چاپ شدن وجود داشته باشه .