Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 2036

แก้ไขปัญหาเรื่อง Callback hell ใน Swift กันนิดหน่อย

$
0
0

swift-callback-hell

swift-callback-hell วันนี้ทำการ review code ทั้งฝั่ง Android และ iOS(Swift) พบว่า code มีสิ่งที่คล้ายกันมาก ๆ คือ มีการเรียกใช้ REST API ผ่าน network library ซึ่งทำงานแบบ Asynchronous สิ่งที่เกิดขึ้นคือ มี feature ที่ต้องเรียกใช้งาน REST API หลาย ๆ ตัวต่อเนื่องกัน ทำให้เกิด code ในรูปแบบของ Callback ซ้อน Callback หรือ Callback hell นั่นเอง หรือดีขึ้นมาหน่อยคือ flow การทำงานของ code กระโดดไปยัง method อื่น ๆ ต่อไปเป็นทอด ๆ หรือ Chain

ผลที่ตามมาก็คือ

  • Developer เองก็งงกับ flow การทำงาน
  • เมื่อต้องทำการเพิ่ม หรือ แก้ไข จะยากมาก ๆ ดังนั้นทำใหม่ดีกว่า !!
  • เรื่องทดสอบไม่ต้องพูดถึง ยากเอาเรื่อง

มาดูรูปแบบของปัญหากันว่าเป็นอย่างไร ?

รูปแบบที่ 1 เป็น Callback hell แบบสนุกสนานมาก ๆ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="1.swift"] รูปแบบที่ 2 ดีขึ้นมาหน่อย เป็นการเรียก method จาก Callback ไปเรื่อย ๆ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="2.swift"] ทั้ง ๆ ที่ความต้องการเป็นดังนี้ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="3.swift"]

มาดูต้นเหตุของปัญหาสิ

เมื่อไปดู code ของ iOS ที่พัฒนาด้วยภาษา Swift 2.3 พบว่าในการเรียกข้อมูลผ่าน REST API นั้น ใช้ Networking Library ซึ่งทำงานแบบ Asynchronous ทั้ง NSURLSession และ Alamorfire การแก้ไขปัญหามีหลายแนวทางทั้ง เปลี่ยนให้เป็น Synchronous สิ !! ใช้ library เพิ่มสิ เช่น Bolt, Promise และ Rx เป็นต้น โดยสิ่งที่ผมเลือกคือ เปลี่ยนการทำงานให้เป็น Synchronous เลยสิ และนำ Grand Central Dispatch (GCD) มาใช้งาน

วิธีการก็ไม่ยากและไม่ง่าย นั่นคือ

สร้าง method ใหม่ใน NSURLSession ผ่าน extension โดย method ใหม่นี้จะทำงานแบบ Synchronous ดังนี้ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="4.swift"] คำอธิบาย จะทำการรอไปจนกว่าจะทำงานเสร็จสิ้นนั่นเอง ซึ่งสามารถตอบโจทย์ที่เราต้องการ จากนั้นในแต่ละ process การทำงานที่ไปดึงข้อมูลผ่าน REST API ใช้งานผ่าน method ใหม่ดังนี้ [gist id="c3828ce256edf981af6c7dbdef6a70a9" file="5.swift"] เพียงเท่านี้ก็สามารถควบคุมการทำงานได้แล้ว แถมได้ code ที่อ่านง่าย แก้ไขง่ายอีกด้วย ปล. 1 ใน Swift 3.0 การใช้งาน GCD ก็จะเปลี่ยนไปโดยสิ้นเชิง ปล. 2 ในการออกแบบ REST API นั้นควรคิดให้มาก ๆ ถ้าต้องให้ client ต้องมาร้อยเรียง service เองมาก ๆ ก็ไม่ใช้การออกแบบที่ดีเลยนะ ที่สำคัญพัฒนายากทั้งฝั่ง API และ Mobile ที่สำคัญยากต่อการ integrate และ ทดสอบอีกด้วย
ดังนั้นมาทำการปรับปรุง code ให้ดีขึ้นกว่าเดิมกันครับ
ตัวอย่าง source code อยู่ที่ Github::Up1::Swift Sync Call

Viewing all articles
Browse latest Browse all 2036

Trending Articles