หากใช้ภาษา Dart หรือ Google Flutter มาถึงจุดหนึ่ง เราจะได้ใช้แนวคิดของการทำงานแบบ Asynchronous หรือ Synchronous แน่นอน
ซึ่งภาษา Dart มีการออกแบบเครื่องมือให้เราใช้สร้างกลไกนี้ง่ายๆ ในชื่อของ Generator Function ครับ
Generator Function
Generator function เป็นวิธีเรียกการเขียนโค้ดส่วนที่ทำให้เราได้ข้อมูลมาเรื่อยๆ โดยที่เราไม่ต้องไปเขียนกลไกการเรียกใช้โค้ดซ้ำซ้อน
ยกตัวอย่างเหมือนเรา ต้องการสร้างคลองลำเลียงน้ำจากแม่น้ำมาเติมในไร่นาของเรา ส่วนของ Generator Function คือส่วนการคลองนี้ครับ

เทียบกับอีกเคสที่ใกล้ตัว Mobile Application เข้ามาอีกนิด ก็คือข้อมูลตลาดหุ้น ที่มีผลกับการแสดงผลกราฟราคาหุ้นในแอพพลิเคชั่นของเรา
ส่วนที่นำข้อมูลมาจาก server ก็สามารถเขียนเป็น Generator Function ได้เช่นกัน

เอาล่ะ มาลองสร้าง Generator Function กัน
สามารถโคลนโปรเจคของพลมาไว้ในเครื่องได้จากคำสั่งนี้
git clone -b starter https://github.com/teerasej/nextflow-flutter-yield-lab
จากนั้นในไฟล์ main.dart ส่วนของ class _MyHomePageState เราจะเขียน function ขึ้นมาอันหนึ่ง
class _MyHomePageState extends State<MyHomePage> {
Stream<int> generateNumber(int max) async* {
int counter = 0;
while (counter < max) {
await Future.delayed(Duration(seconds: 1));
print("going to push stream");
yield counter++;
}
}
...
}
asyncและasync*จะทำให้ function นั้น return ค่าแตกต่างกัน- ถ้าเป็น
asyncfunction จะ return เป็นFuture<dynamic>แต่ในที่นี้ เราใช้async*จะ return เป็นStream<dynamic>แทน - ใน Function ของเรา มีการใช้
Future.delayed()ซึ่งกำหนดการหน่วงเวลา 1 วินาที ก่อนจะไปสู่คำสั่ งyield yieldเป็น keyword พิเศษ ที่จะทำการคืนค่าออกไปจากตัว function (คล้ายๆreturnแต่returnจะจบการทำงานของ function ทันที แต่สำหรับyieldตัว function จะทำงานต่อ)- นั่นทำให้เราสามารถใช้ keyword
yieldในการส่งค่าที่ต้องการออกไปทาง Stream ได้เรื่อยๆ
มาดูการใช้งานกันบ้าง
ในที่นี้ Stream มักจะเอามาใช้กับ StreamBuilder Widget บ่อยๆ เราเลยเอามาใช้งานกับตัว Generator Function ที่สร้างจาก async* กัน
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: StreamBuilder(
stream: generateNumber(10),
builder: (context, snapshot) {
return Text(snapshot.data.toString()
, style: TextStyle(fontSize: 60.0),);
}),
),
);
}
พอเรารันแอพพลิเคชั่นขึ้นมา จะเห็นว่าตัวเลขจะนับเพิ่มขึ้นไปเรื่อยๆ
เป็นเพราะ loop ใน generator function ของเรา พอวิ่งถึงคำสั่ง yield ก็จะมีการส่งค่าออกมาเป็น Stream และเอาไปใช้กับ StreamBuilder Widget ตามที่กำหนดไว้นั่นเอง
โดยการส่งค่ากลับออกมาจาก function ด้วย yield จะไม่เป็นการสิ้นสุดการทำงานแต่อย่างใดครับ

คอร์สออนไลน์เริ่มต้นสร้าง Mobile App ด้วย Google Flutter
เหมาะผู้เริ่มต้น และนักพัฒนาเว็บ, เข้าใจง่าย, ใช้ได้จริง
สอบถาม หรือติดต่อจัดอบรมโทร 083-071-3373
อ้างอิง – Dart Language Tour, StackOverflow