Dart lang: Ep.4 (async, await, then and Future)
ในการทำงานกับ Dart/Flutter เราจะคุ้นเคยกับคำเหล่านี้มาก
เมื่อต้องมีการเรียก API หรือ ใช้งาน Hardware modules ซึ่งถ้ายังสบสน
เดี๋ยวผมจะอธิบายด้วยสมองน้อยๆของผมให้ฟังครับ ว่ามันต่างกันยังไง
- Async หมายความว่า function นี้เป็น asynchronous และจะไม่เกิดขึ้นทันที เราอาจต้องรอสักครู่เพื่อให้ได้รับ result
- Await หมายความว่า ให้รอ รอจนกว่า fucntion นี้จะทำงานเสร็จและจะ return value กลับไป (จะใช้ได้กับ Function ที่เป็น Future เท่านั้นนะ)
- Then((value){…}) คือ callback ที่จะถูกเรียกอีกครั้ง เมื่อ future ได้ทำงานสำเร็จแล้วพร้อมกับมี value ออกมา ซึ่งจริงๆสามารถเพิ่ม .catchError ได้ด้วย กรณีที่ future ทำงานไม่สำเร็จพร้อม error
- Future เป็น Type อย่างหนึ่งที่มีความว่า ‘comes from the future’ และ return value ออกไปจาก Asynchronous function ซึ่งจริงๆแล้ว
ต้องใช้ร่วมกับ keywordaync
ในการสร้าง Future function
และใช้ร่วมกับawait
หรือ.then()
ในการ execute function เช่น
Future<String> bye() async { // ถ้าไม่ใส่ async จะ error นะ
return "Bye bye";
}void main() async {
print(await bye()); // เมื่อต้องใช้ await ก็เช่นต้องมี async เช่นกัน
}
สรุปว่า async จะต้องใช้ใน 2 กรณีคือ
- เมื่อต้องการประกาศให้เป็น Future type (คือจะมีการรอ result แปปนึง)
- เมื่อต้องการเรียกใช้ await ก็ต้องทำให้ function นั้นเป็น async ก่อนเช่นกัน
อธิบายครบล่ะ keywords ทั้ง 4 ตัว ต่อไปมาดูตัวอย่างกันดีกว่าคับ
void main() async {
print(getBreakfast());
print(await getLunch());
print(getDinner().then((String value) => print(value)));
print('The last one go to sleep')
}Future<String> getBreakfast() async {
return "A sandwish";
}Future<String> getLunch() async {
return "A noodle";
}Future<String> getDinner() async {
print('Come to getDinner method');
return "A big fried rice with crab";
}Future<String> bye() { //will not compile, add async
return "see you soon! :)";
}
และจะได้ output แบบนี้
Instance of 'Future<String>'
A noodle
Come to getDinner method
Instance of 'Future<void>'
The last one go to sleep
A big fried rice with crab
อธิบายได้แบบนี้คับ
สรุปได้แบบนี้นะคับ (จุดที่แตกต่างระหว่าง await กับ then)
- เมื่อใช้ await โปรแกรมของเราจะหยุดที่จุดนั้นเลย กระทั่ง function นั้นทำงานเสร็จ เช่น การเรียกใช้กล้อง หรือ เรียก API ที่มีผลกับทั้ง app ถ้าไม่รอที่จังหวะนี้อาจทำให้แอฟพังได้
- แต่ถ้าเราไม่ใช่ await โดย execute ปกติและต่อด้วย .then() จะไม่มีการหยุดที่บรรทัดนั้น แต่จะข้ามไปทำงานบรรทัดถัดไปเลยระหว่างรอ Future function
(ไปตามทางของ async way) และเมื่อ Future ทำงานเสร็จ callback จะทำการ execute ภายหลัง
วิธีนี้อาจเหมาะกับงานที่แสดงผลของข้อมูล อาจให้โชว์ background หรือ ตารางก่อนและ data ค่อยตามมาทีหลังก็ได้ - แต่ถ้าเราใช้ทั้ง await และ .then() จะให้ผลลัพธ์เหมือนกับใช้ await อย่างเดียวนะคับ เพราะต้องรอให้ทำงานสำเร็จ เมื่อมีการ callback อีกครั้งก็จะได้ค่า null
ลองมาดูกันอีกตัวอย่างนะคับ เพราะให้เห็นภาพชัดขึ้น
void main() async {
print('1');
print(await numberTwo());
print('3');
print('4');
print(numberFive().then((result) => print(result)));
print('6');
print('7');
print('8');
print('9');
print('10');
}Future<String> numberTwo() async {
return '2';
}Future<String> numberFive() async {
return '5';
}
โดยจะมี numberTwo() ที่เป็น await และ numberFive() ที่เป็น Future method
ส่วนการเรียกใช้แบบต่างๆ ดู result ได้จากรูปด้านล่างเลยคับ
แล้วพบกันใหม่คับ
GRASSROOT ENGINEER