Flutter: runZonedGuarded เอาไว้ทำอะไรนะ?
Published on
Authored by Pete. Pittawat Taveekitworachai.
เมื่อเราพัฒนาโปรแกรมขึ้นมานั้น ไม่ว่าจะในภาษาใดก็ตาม ข้อผิดพลาด (Error) เป็นสิ่งที่เราไม่อาจหลีกเลี่ยงได้ (Inevitable) แม้ว่าเราจะมั่นใจว่าเรานั้นพัฒนาโปรแกรมมาได้ดีเพียงใดก็ตาม ดังนั้นการแก้ไขข้อผิดพลาดของโปรแกรม (Debugging) จึงอาจถือได้ว่าเป็นหนึ่งในขั้นตอนที่มีความสำคัญอีกส่วนหนึ่งในการพัฒนาโปรแกรม
อย่างไรก็ตามแม้ว่าเราจะตั้งใจพัฒนาให้ดีแค่ไหนก็ตาม แต่ไม่มีอะไรที่สมบูรณ์แบบ ในสภาพแวดล้อมการทำงานแบบนักพัฒนานั้นเรายังสามารถติดตามและแก้ไขข้อผิดพลาดต่าง ๆ ได้อย่างง่ายดาย แต่หากเป็นข้อผิดพลาหลังจากที่เราทำการปล่อยแอปพลิเคชันของเราไปให้ผู้ใช้ได้ใช้งานเรียบร้อยแล้ว นั่นก็ทำให้เป็นเรื่องยากขึ้นที่จะติดตาม
เราจึงต้องอาศัยการเชื่อมต่อกับบริการเฝ้าระวังและติดตามข้อผิดพลาด (Error Monitoring and Tracking Service) เช่น Firebase Crashlytics, Sentry ในการส่งต่อข้อผิดพลาดต่าง ๆ พร้อมข้อมูลเพิ่มเติม เพื่อช่วยให้เราวิเคราะห์ได้ง่ายขึ้น
อย่างไรก็ตามบางครั้งเราก็อาจจะใช้บริการเหล่านี้หลากหลายตัว เพื่อแยกประเภทของข้อผิดพลาดต่าง ๆ ออกจากกัน เช่น ข้อผิดพลดาที่เกิดจาก API ภายนอกที่แอปของเราเชื่อมโยงอยู่ หรือข้อผิดพลาดที่เกิดขึ้นจากแอปพลิเคชันของเราเอง
เราอาจจะสามารถเขียน If-else มาดักการทำงานต่าง ๆ เห่านี้ได้ แต่จะดีกว่ามั้ยถ้ามีฟังก์ชันที่สวยงามและพร้อมให้เราใช้งานได้เลย
ใน Flutter หากเราต้องการจัดการตามเหตุการณ์ดังกล่าวกับ Future
เรามีสิ่งที่เรียกว่า runZoned()
อย่างไรก็ตามในบทความนี้จะพูดถึง runZonedGuarded()
เลย เนื่องจาก runZoned()
นั้นถูกประกาศให้เลิกใช้งาน (Deprecated) ตั้งแต่ Dart 2.8 เป็นต้นมา
Syntax ของ runZonedGuarded()
นั้นจะเป็นดังนี้
runZonedGuarded(futureTask(), errorHandler());
runZonedGuarded()
นั้นเราสามารถนำไปครอบการทำงานที่มีการคืนค่าที่เป็น Future หรืองานที่เป็น Asynchronus Task ต่าง ๆ ได้ โดยมีการส่งข้อมูลนำเข้าเพิ่มเติมไปให้ runZonedGuarded()
อีกหนึ่งตัวนั่นคือฟังก์ชันสำหรับการรับมือกับข้อผิดพลาด (Error Handler) โดยฟังก์ชันนี้นั้นสามารถใช้ทดแทน .catchError()
ตามปกติได้เลย และ runZonedGuarded()
จะส่งของมาให้สองอย่างนั่นคือ Map
ที่โดยปกติมักจะเป็น Error ที่เกิดขึ้น และ ZoneSpecification
ซึ่งเป็น Object ที่มีการเก็บข้อมูลเพิ่มเติมเกี่ยวกับ Zone ไว้ และอนุญาตให้เราสามารถปรับแต่งค่าบางอย่างให้กับ Zone ได้
ตัวอย่างเช่น
runZonedGuarded(() {
Future(() {
throw "asynchronous error";
});
},
(e, s) => print(e)
);
จากตัวอย่างโค้ด จะเห็นได้ว่าเรานำ runZonedGuarded()
ไปครอบให้กับ Future ซึ่งทำอย่างเดียว นั่นคือการ throw
ข้อผิดพลาดออกมา ซึ่งหลังจากที่เกิดข้อผิดพลาด ขึ้นแล้วแทนที่จะลอยขึ้นไปตามลำดับชั้น จนอาจส่งผลให้แอปพลิเคชันของเราหยุดการทำงานนั้น ก็จะเข้าไปที่ Error Handler แทน ซึ่งภายใน Error Handler นั้น เราก็เขียนให้แสดงผลลัพธ์ของข้อผิดพลาดนั้นออกมา
ตรงจุดนี้เองแทนที่เราจะแสดงผลลัพธ์ออกมา เราสามารถประยุกต์ใช้ด้วยการส่งต่อให้กับบริการติดตามข้อผิดพลดาดังที่กล่าวไปข้างต้น โดยเราอาจจะเพิ่มเติมข้อมูลต่าง ๆ เข้าไปด้วยก็ได้เช่นกัน
การประยุกต์ใช้อื่น ๆ สำหรับ runZonedGuarded()
ก็อาจเป็นการที่เราต้องการแยกบางส่วนของโปรแกรมออกมา ไม่ให้ข้อผิดพลาดที่เกิดขึ้นจากส่วนนั้น ๆ ไปยุ่งเกี่ยวกับส่วนอื่น ๆ นั่นเอง
สำหรับคนที่สนใจศึกษาเพิ่มเติม สามารถอ่านได้ที่ Flutter API Reference