Google Flutter

Flutter: วิธีการใช้ yield และ async ใน Generator function ของภาษา Dart

เรื่องที่เกี่ยวข้อง - ,

หากใช้ภาษา 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

Loading Facebook Comments ...
Menu