RX Operation Merge vs Zip ใช้อันไหนให้ดี Implement แบบไหนให้โดน

Thanawat Masileerungsri
3 min readDec 2, 2018

--

มารู้จักกันทีละอันกันดีกว่า ก่อนอื่นใครที่หลงเข้ามา โดยไม่รู้ว่า RX คืออะไร ขอเล่าให้ฟังคร่าวๆ ก่อนเลย

เคยสงสัย Operator ของ RX ไหมครับ ระหว่าง Zip กับ Merge เลือกอะไรดี

RX คือ Paradiam ในการเขียนโปรแกรมแบบนึง โดย Paradiam ในที่นี้ จะคล้ายๆกับ Style เช่น Object Oriented Programing, Functional Programming หรือ Aspect Object Oriented Programing ซึ่งชื่อที่กล่าวมาทั้งหมด ทั้งมวลเป็น Paradiam ในการเขียน Program ทีนี้มารู้จักกับ คุณ RX กัน

ชื่อเต็มๆของ RX คือ Reactive Programming โดยแก่น ความสามารถ ที่จะนับว่าเป็น RX มีอยู่ 2 เรื่องคือ Asynchonous กับ Data Live …… เกริ่นเท่านี้แหละ detail หาเพิ่มเติมที่ https://medium.com/@nutron/what-is-reactivex-38293abb81cb

ที่นี้มาเข้าเรื่องที่อยากจะแชร์ ให้ทุกคนฟังกัน คือ ตัวผมเองยังไม่ค้อย ไม่ค่อย เข้าใจในการทำงาน Operation ของ RX อยู่คู่นึง คือ เจ้า Merge กับ เจ้า Zip ทั้งคู่ จัดอยู่ในหมวดของ Composition Operator โดย Operation กลุ่มนี้ มีความหมายว่า หากเราต้องการทำงาน ลักษณะที่มีความเกี่ยวเนื่องกันในตอนสิ้นสุดการทำงาน หรือ พูดโดยง่ายๆคือ มีงานหลายๆอย่างทำงานพร้อมกันอยู่ เมื่อมีงานทำเสร็จแล้วอยากทำอีกงานนึง โดยมีอันนึงที่ รอทุกอันทำเสร็จ แล้วทำทีเดียว ส่วนอีกอัน ถ้ามีอันไหนเสร็จก็เอามาทำงานส่วนสุดท้ายก่อน

ปล. แค่อยากจะบอกว่ากว่าจะประดิษฐ์คำให้เป็นเป็นคำไทยได้ ลบไปแล้วประมาณ 10 รอบ ไม่เข้าใจตรงไหน วนลูปอ่านเลยครับ read++;

ซึ่งตอนแรกก็ถกเถียงกับคนที่รู้จักกันตั้งนาน 2 นาน จนสุดท้าย ก็ทดลอง ทดสอบการทำงานของมัน โดยกำหนดให้งานที่ต้องการทำเป็นการ ทำงานของ Thread แต่ละเส้นโดยมีระยะเวลาการทำงานที่ต่างกัน ก่อนจะแว๊ปไปทำการทดลอง อยากจะอธิบายความสามารถของ Merge กับ Zip กันก่อน

Merge Operation - ภาพจาก http://reactivex.io/documentation/

Merge Operation

ความสามารถของมันคือ Operation Merge จะรวมของที่ถูก call เข้าด้วยกัน โดย ของแต่ละอันที่ถูก call นั้นสามารถส่ง callback update operation merge ได้ ซึ่งหากอันไหนทำงานเสร็จก่อน ก็จะทำการ Merge ก่อน

Zip Operation - ภาพจาก http://reactivex.io/documentation/

Zip Operation

ส่วน zip จะถูก trigger ทีเดียวเมื่อทุกอันทำงานเสร็จแล้ว หรือ เมื่อมีอันใดอันนึง failed ก็จะถูก trigger error ออกมา เมื่อทุกอันทำงานเสร็จถึงจะเริ่ม Process Zip

ทีนี้ ความน่าสนใจจะอยู่ที่ ความต้องการใช้งานของเรา ว่าเราควรใช้งานตัวไหนมากกว่ากัน จึงนำมาสู่กระบวนการทดลอง

วัตถุประสงค์การทดลอง

เราจะทำการทดสอบเพื่อชี้ให้เห็นถึงความแตกต่าง ของการทำงานใน Operation Zip กับ Operation Merge บน RX โดยจะทดสอบ
- การทำงานปกติ
- การทำงานแบบผิดปกติบางส่วน

เครื่องมือที่ใช้

RxJava 2.x.x
https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0

ขั้นตอนการทดลอง

โจทย์มีอยู่ว่า มีระบบขายของ online อยู่ระบบนึงซึ่งมี API เดิมอยู่แล้ว อยากเพิ่ม feature คำนวณหาความโชคดีของ User ที่จะได้รับส่วนลดเพิ่มเติม ซึ่งมีเงื่อนไขคือ ทำจาก API ที่มีบนระบบเดิมเท่านั้น (เพื่อจะได้ทดลอง Operation ของ RX )ได้แก่

  1. User Profile เป็น API เกี่ยวกับ Profile ของ User ซึ่งเปิดดูหมวดสินค้าอะไรอยู่โดยจะมี name, id, level, expToNextLevel, userExp, currentCategory

2. Fortune Queue เป็น API ระบุลำดับที่ User ที่เข้ามาในระบบในวันนั้น เพื่อ Lock การสุ่มรางวัล โดยจะมี entryNo, entryTime, luckyScale(1–10)

3. Lucky Category เป็น API จาก AI ที่จะ Random หาหมวดสินค้า และ ลำดับที่ User เข้ามาในระบบ หากซื้อสินค้าตามหมวด Random และลำดับที่ User ตรงก็จะได้รับส่วนลดแบบพิเศษ โดยจะมี category, entryNo, discountRate

เราจะให้ App ทำหน้าที่ call request ทั้ง 3 API แล้ว เอา Result มาเข้า logic เพื่อคำนวณหาผู้โชคดีจาก Logic นี้

Logic สำหรับการหาผู้โชคดี

เราจะใช้ RX Operation ในการแก้ปัญหานี้ โดยจะ Combine Result ของ API ที่มีอยู่ทีนี้ เรามาลองทำการทดลองเลยดีกว่า

เพื่อให้สามารถรันได้ เราก็ต้องเขียน class Experiment ขึ้นมาลองรันดูซึ่งเราจะแบ่งการทดลองเป็น 2 case ได้แก่ Request API ได้ปกติ และ Request API ไม่ได้บาง Request

CASE: Request API ได้ปกติ

  • Request API ได้ปกติ พบว่าการใช้งาน Merge กับ Zip หาความต่างไม่ในแง่ในการทำจนเสร็จ แต่จะต่างตรงที่ Merge จะค่อยๆเอามารวมกันทุกๆครั้งที่มีคนเสร็จ แต่ Zip จะเอา Result จากก้อน 1, 2, 3 มารวมกันทีเดียว

CASE: Request API ไม่ได้บาง Request

  • Request API ไม่ได้บาง Request พบว่าการทำงานแบบนี้จะมีความแตกต่างระหว่าง Merge กับ Zip อย่างชัดเจน คือ Merge นั้นสามารถเขียนให้ Detect ได้ว่าอันไหนทำสำเร็จไปแล้วบ้าง แต่ Zip ไม่สามารถระบุได้ว่างานไหนที่ได้ทำไปแล้วและหากอันใดอันนึงผิดพลาด ก็จะหยุดทั้งกระบวนการไปเลย

สรุปผลการทดลอง

จากการทดลองจะเห็นว่า การทำงานของ Merge กับ Zip จะต่างกันตรงที่ Merge จะค่อยๆ Increment ของซึ่งจะเหมาะกับงานที่ไม่จำเป็นต้องรอ แต่ Zip จะทำรวบเดียวตอนจบเลย

Material

ทุกคนลองไปเล่นดาวน์โหลด Project ไปเล่นดูได้ที่ ซึ่งจะยังไม่ได้ implement
https://github.com/ThanawatMas/RxMergeAndZipExperiment

ทั้งนี้ส่วนที่เป็นการคำนวณหาความโชคดี ลองมาเขียนโค้ดกันนะครับ
ว่าแล้วขอตัวก่อนสำหรับวันนี้แล้วเจอกันใหม่บทความหน้า Sayonara (=.= ).zZ

========================================

“ใครใคร่ใช้อะไรใช้ แต่ถ้าไม่ใคร่ใช้ แล้วใครจะใช้ ”

= — The end — =

--

--

No responses yet