หากใช้ภาษา 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 ค่าแตกต่างกัน- ถ้าเป็น
async
function จะ 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