เขียน Swift ให้เรียก API พร้อมกัน และรอจนเสร็จทุกเส้น ด้วย Dispath Group

Burin Techama
1 min readAug 11, 2020

--

DispatchGroup ตัวช่วยในการทำงานที่มีเงื่อนไขเกี่ยวกับเวลาเข้ามาเกี่ยวข้อง ช่วยให้เราสามารถควบคุมการทำงานของโปรแกรมกับเวลาให้เป็นไปตามเงื่อนไขได้

หลายคนคงรู้จักกับ Dispath มาบ้างแล้ว เช่น ในเงื่อนไขที่เราเรียก API และเราต้องรอให้ข้อมูลจาก API รีเทิร์นมาก่อน โปรแกรมถึงจะทำงานในขั้นตอนถัดไปได้ ซึ่งเจ้าตัว DispathGroup นี้ก็ทำงานในหลักการเดียวกัน แต่แทนที่เราจะรอแค่อันเดียว ตอนนี้เราจะเปลี่ยนเป็นรอเป็นกลุ่มแทน

ขั้นตอนของการใช้งาน DispathGroup

ในตอนนี้เราจะจำลองสถานการณ์ของการเรียก API Upload ที่ต้องเรียก เพื่ออัพโหลดไฟล์รูปและวิดีโอพร้อมกันหลายๆไฟล์ แล้วนำข้อมูลที่ได้จาก API Upload ไปเป็นข้อมูลในการเรียก API ตัวสุดท้ายคือ API requestAddData ครับ

อันดับแรกสร้างตัวแปร DispathGroup ขี้นมารอไว้เลยยย

ขั้นตอนถัดมา ในการเรียก API อัพโหลดไฟล์รูปและไฟล์วิดีโอเราจะเรียกใช้งานฟังก์ชัน dispathGroup.enter() ทุกครั้งที่เราเรียก API และเรียกฟังก์ชั่น dispathGroup.leave() เมื่อเสร็จสิ้นการอัพโหลด โดยสามารถเขียนโค้ดได้ดังนี้

ในขั้นตอนของการเรียก API อัพโหลดรูปและวิดีโอ ต้องจำไว้เสมอว่า เมื่อเราสั่ง enter ไปกี่ครั้ง เราต้องทำการสั่ง leave ไปเท่ากับจำนวนนั้น

ส่วนฟังก์ชั่น uploadVideo ก็จะทำงานคล้ายกับฟังก์ชั่น updateImage โดยเมื่อเริ่มต้นสั่งงานก็จะมีการเรียก dispathGroup.enter() และเมื่อจบการทำงาน ก็จะมีการสั่ง leave() แบบเดียวกัน

เมื่อมีการเรียก leave ครบตามจำนวนที่สั่ง enter ไป ฟังก์ชั่น notify จะทำงานโดยอัตโนมัติ ซึ่งเราสามารถเขียนฟังก์ชันเพื่อเรียกการทำการของฟังก์ชั่น notify ได้ดังนี้

เมื่อการอัพโหลดทุกไฟล์สำเร็จ ฟังก์ชั่น notify ทำงาน โปรแกรมก็จะทำฟังก์ชัน requestAddData ซึ่งเป็น API ตัวสุดท้ายต่อไป

ซึ่งเมื่อเรานำมาประกอบกับฟังก์ชันอัพโหลดรูปที่แยกตามประเภทของเนื้อหา ก็จะสามารถเขียนโค้ดได้ดังนี้

ซึ่งเมื่อเราเรียกใช้ฟังก์ชั่น requestUploadMedia จะทำให้การเรียก API Upload ทั้งหมดเกิดขึ้นพร้อมกัน และมีตัว dispathGroup เป็นตัวตรวจดูการทำงานของการเรียก API ทุกตัว และเมื่อการเรียก API เสร็จสิ้น โดยจะสังเกตุได้จาก dispathGroup จะถูกสั่ง leave ออกจนหมด ตัว dispathGroup ก็จะทำหน้าที่ต่อไปคือ notify ซึ่งก็จะสั่งให้ทำฟังก์ชั่น requestAddData ต่อไป

--

--