FutureBuilder — คืออะไร การทำงานกับ Future ใน Flutter

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-02 เวลาอ่าน: 8 นาที

FutureBuilder คือวิดเจ็ตใน Flutter ที่สร้างอินเทอร์เฟซขึ้นใหม่โดยอัตโนมัติตามสถานะปัจจุบันของ AsyncSnapshot ที่ได้รับจาก Future ที่ส่งเข้าไป แตกต่างจากการเรียก setState ด้วยตนเองหลังจาก await FutureBuilder มีแนวทางการทำงานแบบประกาศ: มันสมัครสมาชิก Future ในการเรนเดอร์ครั้งแรกและเรียกฟังก์ชัน builder ทุกครั้งที่มีการเปลี่ยนแปลงสถานะ — โหลด ข้อผิดพลาด หรือข้อมูลพร้อมใช้งาน ตาม Flutter API Reference (2026) FutureBuilder มีประโยชน์อย่างยิ่งสำหรับการโหลดข้อมูลจากเครือข่าย การอ่านจากฐานข้อมูล และการดำเนินการแบบอะซิงก์ใด ๆ ที่ UI ต้องแสดงตัวบ่งชี้การโหลด ข้อความแสดงข้อผิดพลาด หรือเนื้อหาที่พร้อมใช้งาน

ประเด็นสำคัญ

  • FutureBuilder — วิดเจ็ต Flutter สำหรับสร้าง UI ตามสถานะ Future ผ่าน AsyncSnapshot (none, waiting, active, done)
  • AsyncSnapshot — ออบเจ็กต์ที่มีสถานะปัจจุบันของการดำเนินการแบบอะซิงก์: connectionState, data และ error
  • builder — ฟังก์ชันเรียกกลับที่ถูกเรียกทุกครั้งที่มีการเปลี่ยนแปลงสถานะ Future เพื่อสร้าง UI ใหม่
  • การจัดการข้อผิดพลาด — AsyncSnapshot.hasError อนุญาตให้แสดง UI สำรองเมื่อการดำเนินการแบบอะซิงก์ล้มเหลว
  • ConnectionState — เอนัมที่มีสี่ค่า: none (ไม่มีการดำเนินการ), waiting (กำลังรอ), active (สตรีม), done (เสร็จสมบูรณ์)

FutureBuilder ใน Flutter คืออะไร

FutureBuilder คือวิดเจ็ต Flutter ในตัวจากแพ็กเกจ widgets ที่รับ Future และฟังก์ชัน builder เมื่อสถานะของ Future เปลี่ยนแปลง (กำลังทำงาน เสร็จสมบูรณ์พร้อมข้อมูล เสร็จสมบูรณ์พร้อมข้อผิดพลาด) FutureBuilder จะสร้าง UI ใหม่โดยอัตโนมัติโดยเรียก builder ด้วย AsyncSnapshot ใหม่ ซึ่งช่วยขจัดความจำเป็นในการจัดการสถานะการโหลดด้วยตนเองผ่าน setState และแฟล็ก

แตกต่างจาก StreamBuilder ที่ทำงานกับสตรีมข้อมูล (Stream) FutureBuilder ถูกออกแบบมาสำหรับการดำเนินการแบบอะซิงก์ครั้งเดียว: คำขอ HTTP การอ่านไฟล์ การสอบถามฐานข้อมูล FutureBuilder จัดการการสมัครสมาชิก Future ด้วยตัวเอง: ในการสร้างครั้งแรก มันจะเริ่ม Future และติดตามความสำเร็จ เมื่อวิดเจ็ตถูกทำลาย FutureBuilder จะไม่ยกเลิก Future — นั่นคือความรับผิดชอบของนักพัฒนา

ตาม Flutter Cookbook (2026) FutureBuilder ถูกแนะนำสำหรับกรณีที่การดำเนินการแบบอะซิงก์ทำงานครั้งเดียวเมื่อเริ่มต้นหน้าจอ สำหรับการดำเนินการที่เกิดขึ้นซ้ำหรือสตรีมข้อมูล ให้ใช้ StreamBuilder วิดเจ็ตทั้งสองปฏิบัติตามรูปแบบ UI เชิงโต้ตอบเดียวกัน แต่ FutureBuilder ถูกปรับให้เหมาะสมสำหรับคำขอครั้งเดียว

FutureBuilder ทำงานภายในอย่างไร

การทำงานภายในของ FutureBuilder สมัครสมาชิก Future โดยใช้ Future.then และ catchError เมื่อ FutureBuilder เริ่มทำงาน มันจะตั้งค่า connectionState เป็น ConnectionState.waiting และเรียก builder ด้วยข้อมูลว่าง เมื่อเสร็จสมบูรณ์สำเร็จ connectionState เปลี่ยนเป็น ConnectionState.done พร้อมข้อมูล เมื่อเกิดข้อผิดพลาด snapshot.error จะถูกเติมด้วยออบเจ็กต์ข้อผิดพลาด การเปลี่ยนแปลงแต่ละครั้งจะทริกเกอร์การสร้างวิดเจ็ตใหม่

AsyncSnapshot: สถานะและคุณสมบัติ

AsyncSnapshot คือออบเจ็กต์คอนเทนเนอร์ที่ FutureBuilder ส่งไปยังฟังก์ชัน builder ทุกครั้งที่มีการเปลี่ยนแปลงสถานะ มันมีข้อมูลทั้งหมดเกี่ยวกับสถานะปัจจุบันของการดำเนินการแบบอะซิงก์: กำลังโหลดอยู่หรือไม่ ได้รับข้อมูลใดหรือเกิดข้อผิดพลาดหรือไม่ การเข้าใจ AsyncSnapshot เป็นกุญแจสำคัญในการสร้าง UI อย่างถูกต้องกับ FutureBuilder

คุณสมบัติชนิดคำอธิบาย
connectionStateConnectionStateสถานะการเชื่อมต่อปัจจุบัน (none, waiting, active, done)
dataT?ข้อมูลที่ได้รับจาก Future (null จนกว่าจะเสร็จสมบูรณ์หรือเมื่อเกิดข้อผิดพลาด)
errorObject?ออบเจ็กต์ข้อผิดพลาดหาก Future เสร็จสมบูรณ์ด้วยข้อยกเว้น
hasDatabooltrue ถ้า data ไม่ใช่ null และ connectionState เป็น ConnectionState.done
hasErrorbooltrue ถ้า Future เสร็จสมบูรณ์ด้วยข้อผิดพลาด

ConnectionState: สี่สถานะของการดำเนินการแบบอะซิงก์

เอนัม ConnectionState กำหนดขั้นตอนของการดำเนินการแบบอะซิงก์ None — สถานะเริ่มต้นเมื่อ Future ยังไม่ได้เริ่ม (ไม่ค่อยได้ใช้ โดยทั่วไปในการสร้างครั้งแรกโดยไม่มี initialData) Waiting — Future กำลังทำงาน ข้อมูลยังไม่ได้รับ Active — ใช้โดย StreamBuilder เท่านั้นสำหรับสตรีมที่มีข้อมูลบางส่วน Done — Future เสร็จสมบูรณ์ ข้อมูลพร้อมใช้งานผ่าน snapshot.data หรือข้อผิดพลาดผ่าน snapshot.error

การจัดการสถานะ AsyncSnapshot ทั้งหมดอย่างถูกต้องในฟังก์ชัน builder เป็นข้อกำหนดบังคับสำหรับโค้ดในระบบผลิต หากคุณไม่จัดการสถานะ waiting ผู้ใช้จะเห็นหน้าจอว่างระหว่างการโหลด หากคุณไม่จัดการ hasError ผู้ใช้จะได้รับข้อยกเว้นโดยไม่มีคำอธิบาย รูปแบบที่แนะนำ: ตรวจสอบ hasError → ตรวจสอบ hasData → แสดงการโหลดตามค่าเริ่มต้น

รูปแบบการใช้งาน FutureBuilder

FutureBuilder สามารถใช้ได้ในหลายรูปแบบมาตรฐาน แต่ละรูปแบบแก้ปัญหาเฉพาะเจาะจง มาดูสถานการณ์หลัก: การโหลดข้อมูลเมื่อเริ่มต้น การโหลดด้วยแคช คำขอแบบขนาน และการจัดการข้อผิดพลาดด้วยการลองใหม่

การโหลดข้อมูลเมื่อเริ่มต้นหน้าจอ

รูปแบบที่พบบ่อยที่สุด — FutureBuilder ในเมธอด build ของ StatefulWidget หรือ StatelessWidget Future ถูกส่งจาก initState หรือสร้างโดยตรงใน build สิ่งสำคัญคือไม่ต้องสร้าง Future ในเมธอด build ทุกครั้งที่มีการสร้างใหม่ — ซึ่งจะนำไปสู่คำขอซ้ำ ๆ ใช้ Future ที่เก็บไว้ในฟิลด์ State

การโหลดด้วยแคชและการรีเฟรช

เพื่อป้องกันคำขอซ้ำ ๆ FutureBuilder สามารถรวมกับ CachedNetworkImage หรือแคชภายในเครื่อง หลังจากการโหลดครั้งแรก ข้อมูลจะถูกบันทึกในหน่วยความจำหรือ SharedPreferences และ FutureBuilder จะแสดงข้อมูลที่แคชไว้ทันทีพร้อมกับรีเฟรชจากเครือข่ายแบบขนาน ซึ่งช่วยปรับปรุงประสบการณ์ผู้ใช้ด้วยการตอบสนองทันที

ตาม pub.dev (2026) การแคชมีความสำคัญอย่างยิ่งสำหรับรูปภาพและรายการข้อมูล FutureBuilder กับ CachedNetworkImageProvider จะแสดงรูปภาพที่แคชไว้โดยอัตโนมัติ และเมื่อไม่มี — ตัวบ่งชี้การโหลดตามด้วยไฟล์ที่ดาวน์โหลด

FutureBuilder กับ setState: เลือกอะไรดี

FutureBuilder และการจัดการสถานะด้วยตนเองผ่าน setState เป็นสองแนวทางสำหรับ UI แบบอะซิงก์ใน Flutter แต่ละแบบมีข้อดีและข้อจำกัดของตัวเอง การเลือกขึ้นอยู่กับความซับซ้อนของหน้าจอและจำนวนการดำเนินการแบบอะซิงก์

FutureBuilder ชนะในเรื่องความเรียบง่าย: คุณไม่จำเป็นต้องประกาศฟิลด์สำหรับสถานะการโหลด ข้อมูล และข้อผิดพลาด — ทุกอย่างถูกจัดการผ่าน AsyncSnapshot มันเหมาะสำหรับหน้าจอที่เรียบง่ายที่มีการดำเนินการแบบอะซิงก์เดียว (คำขอ HTTP หนึ่งครั้ง การอ่านฐานข้อมูล) อย่างไรก็ตาม เมื่อมี 5+ การดำเนินการแบบอะซิงก์บนหน้าจอเดียว FutureBuilder จะสร้างการซ้อนที่มากเกินไป — ส่งผลให้เกิด “พีระมิด” ของ FutureBuilder ที่ซ้อนกัน

setState พร้อมแฟล็กสถานะด้วยตนเองให้การควบคุมและการอ่านที่มากขึ้นสำหรับตรรกะที่ซับซ้อน สำหรับหน้าจอที่มีคำขอที่พึ่งพากันหลายรายการ (โหลดผู้ใช้ → โหลดคำสั่งซื้อ → โหลดรายละเอียดคำสั่งซื้อ) ควรใช้ setState กับ ChangeNotifier หรือ Bloc ตาม Flutter State Management Guide (2026) สำหรับสถานการณ์ที่ซับซ้อน แนะนำให้ใช้ Riverpod หรือ Bloc แทน FutureBuilder เนื่องจากให้การแยกตรรกะและการนำเสนอที่ดีกว่า

ตัวอย่าง FutureBuilder โหลดข้อมูลเครือข่าย

ลองพิจารณาตัวอย่างเชิงปฏิบัติของ FutureBuilder สำหรับการโหลดรายชื่อผู้ใช้จาก REST API โค้ดสาธิตการจัดการที่ถูกต้องของทั้งสามสถานะ AsyncSnapshot: การโหลด ข้อผิดพลาด และข้อมูลพร้อมใช้งาน

dart
class UserListPage extends StatefulWidget {
  const UserListPage({super.key});

  @override
  State<UserListPage> createState() => _UserListPageState();
}

class _UserListPageState extends State<UserListPage> {
  final Future<List<User>> usersFuture = UserRepository().fetchUsers();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('ผู้ใช้')),
      body: FutureBuilder<List<User>>(
        future: usersFuture,
        builder: (context, AsyncSnapshot<List<User>> snapshot) {
          if (snapshot.hasError) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Icon(Icons.error_outline, size: 48, color: Colors.red),
                  const SizedBox(height: 16),
                  Text('ข้อผิดพลาด: ${snapshot.error}'),
                ],
              ),
            );
          }

          if (snapshot.hasData) {
            final users = snapshot.data!;
            return ListView.builder(
              itemCount: users.length,
              itemBuilder: (context, index) {
                return ListTile(
                  leading: CircleAvatar(backgroundImage: NetworkImage(users[index].avatarUrl)),
                  title: Text(users[index].name),
                  subtitle: Text(users[index].email),
                );
              },
            );
          }

          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

ในตัวอย่าง FutureBuilder จัดการทั้งสามสถานะ เมื่อเกิดข้อผิดพลาด จะแสดงไอคอนพร้อมข้อความแสดงข้อผิดพลาด เมื่อโหลดสำเร็จ — ListView พร้อมรูปประจำตัวและชื่อ ระหว่างการโหลด — CircularProgressIndicator Future ถูกประกาศเป็นฟิลด์คลาส ซึ่งป้องกันการเรียกซ้ำเมื่อสร้างใหม่ รูปแบบนี้ครอบคลุม 90% ของสถานการณ์การใช้งาน FutureBuilder ในแอปมือถือ

คำถามที่พบบ่อย

ทำไม FutureBuilder ถึงเรียก builder หลายครั้ง?

FutureBuilder เรียก builder ทุกครั้งที่มีการเปลี่ยนแปลงสถานะ Future: ครั้งแรกเมื่อสร้าง (connectionState: none หรือ waiting) ครั้งที่สองเมื่อเสร็จสมบูรณ์ (connectionState: done) หากวิดเจ็ตพ่อแม่ถูกสร้างใหม่ FutureBuilder ก็จะถูกสร้างใหม่เช่นกัน เพื่อป้องกันการเรียกซ้ำ ตรวจสอบให้แน่ใจว่า Future ถูกสร้างภายนอกเมธอด build — มิฉะนั้นทุกการเรียก build จะสร้าง Future ใหม่

จะป้องกันคำขอซ้ำเมื่อสร้างใหม่ได้อย่างไร?

เก็บ Future ในฟิลด์ StatefulWidget (ใน initState) หรือใช้การจดจำ หาก Future ถูกสร้างภายในเมธอด build ทุกการเรียก build จะสร้าง Future ใหม่ และ FutureBuilder จะเริ่มการดำเนินการแบบอะซิงก์ใหม่ สำหรับ StatelessWidget ให้ใช้แพ็กเกจ cached_future หรือวิดเจ็ต keep-alive เพื่อให้ Future ทำงานครั้งเดียวโดยไม่ขึ้นกับการสร้างใหม่

FutureBuilder แตกต่างจาก StreamBuilder อย่างไร?

FutureBuilder ออกแบบมาสำหรับการดำเนินการแบบอะซิงก์ครั้งเดียว (คำขอ HTTP หนึ่งครั้ง การอ่านฐานข้อมูลหนึ่งครั้ง) StreamBuilder ทำงานกับสตรีมข้อมูลที่สามารถส่งหลายค่าเมื่อเวลาผ่านไป (แชท การอัปเดตราคา ตำแหน่งทางภูมิศาสตร์) StreamBuilder รองรับ ConnectionState.active สำหรับข้อมูลบางส่วน ในขณะที่ FutureBuilder รองรับเฉพาะ waiting และ done

จะใช้ FutureBuilder กับ Future หลายตัวได้อย่างไร?

สำหรับ Future แบบขนานหลายตัว ให้ใช้ Future.wait และส่งผลลัพธ์ไปยัง FutureBuilder ตัวเดียว Future.wait รับรายการ Future และส่งคืน Future — เมื่อ Future ทั้งหมดเสร็จสมบูรณ์ builder จะได้รับอาร์เรย์ของผลลัพธ์ สำหรับคำขอตามลำดับ ให้ใช้เชน Future.then ภายใน Future เดียวหรือ FutureBuilder ที่ซ้อนกัน (อ่านยากกว่า) ทางเลือกคือแพ็กเกจ riverpod กับ AsyncValue สำหรับสถานะแบบอะซิงก์หลายสถานะ

จะยกเลิก Future เมื่อออกจากหน้าจอได้อย่างไร?

FutureBuilder ไม่ได้ยกเลิก Future โดยอัตโนมัติ หากต้องการยกเลิก ให้ใช้ CancelableOperation จากแพ็กเกจ async หรือกลไกแบบกำหนดเองผ่านแฟล็ก cancelled ใน State ตั้งค่าแฟล็กใน dispose() และตรวจสอบหลังจาก Future เสร็จสมบูรณ์ก่อนเรียก setState หรือใช้แพ็กเกจ riverpod กับ AutoDispose ซึ่งจะยกเลิกการดำเนินการแบบอะซิงก์โดยอัตโนมัติเมื่อออกจากหน้าจอ

สรุป

  • FutureBuilder — วิดเจ็ต Flutter สำหรับสร้าง UI เชิงประกาศตามสถานะ Future ผ่าน AsyncSnapshot (waiting, done, error)
  • AsyncSnapshot — คอนเทนเนอร์ที่มี connectionState, data และ error; จำเป็นสำหรับการจัดการสถานะการดำเนินการแบบอะซิงก์ทั้งหมดอย่างถูกต้อง
  • builder — ฟังก์ชันเรียกกลับที่มีสามสาขา: hasError (แสดงข้อผิดพลาด), hasData (แสดงข้อมูล), default (ตัวบ่งชี้การโหลด)
  • FutureBuilder กับ setState — FutureBuilder ง่ายกว่าสำหรับการดำเนินการเดียว setState กับ Bloc/Riverpod ดีกว่าสำหรับตรรกะซับซ้อนที่มีหลายคำขอ
  • การป้องกันคำขอซ้ำ — Future ควรเป็นฟิลด์ State อย่าสร้างในเมธอด build เพื่อหลีกเลี่ยงการเริ่มใหม่ทุกครั้งที่สร้าง
  • การยกเลิก Future — FutureBuilder ไม่ได้ยกเลิก Future เมื่อ dispose; ใช้ CancelableOperation หรือแฟล็กยกเลิกเพื่อป้องกัน setState หลังการทำลาย
  • Future หลายตัว — สำหรับคำขอแบบขนานใช้ Future.wait กับ FutureBuilder เดียว; สำหรับตามลำดับ — เชนใน Future เดียว

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม