การเชื่อมต่อด้วย thenApply และ thenCompose
แปลงผลลัพธ์ด้วย thenApply และเชื่อมขั้นตอนอะซิงโครนัสแบบ flatMap ด้วย thenCompose เพื่อหลีกเลี่ยง future ซ้อนกัน
การเชื่อมต่อด้วย thenApply และ thenCompose เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
thenApply: แปลงผลลัพธ์
thenApply(Function) ใช้ฟังก์ชันแบบทำงานทันทีแปลงผลลัพธ์ของฟิวเจอร์ที่เสร็จสมบูรณ์แล้ว และส่งคืนฟิวเจอร์ใหม่ที่มีชนิดผลลัพธ์ที่แปลงแล้ว เมธอดนี้ไม่ได้เริ่มงานอะซิงก์ใหม่
CompletableFuture<String> nameFuture = CompletableFuture
.supplyAsync(() -> 42L) // CF<Long>
.thenApply(id -> "User#" + id); // CF<String>
System.out.println(nameFuture.join()); // "User#42"thenApplyAsync: แปลงผลลัพธ์บนเธรด
thenApplyAsync เรียกใช้ฟังก์ชันแปลงผลลัพธ์บน ForkJoinPool หรือผู้ดำเนินการที่ระบุ ทำให้เธรดที่ทำให้ฟิวเจอร์เสร็จสมบูรณ์ทำงานต่อได้ทันที
CompletableFuture<String> result = fetchUserAsync()
.thenApplyAsync(user -> serialize(user)); // runs on pool threadthenAccept: ใช้ผลลัพธ์โดยไม่ส่งคืนค่า
thenAccept(Consumer) ประมวลผลผลลัพธ์แต่ส่งคืน CompletableFuture<Void> ใช้เป็นขั้นตอนสุดท้ายในกระบวนการทำงานเมื่อไม่ต้องการส่งค่าต่อไป
fetchUserAsync()
.thenApply(User::getName)
.thenAccept(name -> System.out.println("Hello, " + name));thenRun: ทำงานหลังเสร็จสมบูรณ์
thenRun(Runnable) เรียกใช้งานหลังจากฟิวเจอร์เสร็จสมบูรณ์ โดยไม่สนใจผลลัพธ์ เหมาะสำหรับการปิดทรัพยากรหรือเรียกใช้ผลข้างเคียง
downloadFileAsync(url)
.thenRun(() -> System.out.println("Download complete"));การเชื่อมต่อการเรียก thenApply หลายครั้ง
การเรียก thenApply หลายครั้งจะก่อให้เกิดกระบวนการทำงานต่อเนื่อง แต่ละขั้นตอนจะได้รับผลลัพธ์จากขั้นตอนก่อนหน้า
CompletableFuture<Double> result = CompletableFuture
.supplyAsync(() -> " 42.5 ")
.thenApply(String::trim)
.thenApply(Double::parseDouble)
.thenApply(d -> d * 1.21); // apply 21% VAT
System.out.println(result.join()); // 51.425thenCompose: คลี่ฟิวเจอร์ซ้อนกัน
thenCompose(Function<T, CompletionStage<U>>) ทำงานคล้าย flatMap สำหรับฟิวเจอร์ โดยหลีกเลี่ยง CompletableFuture<CompletableFuture<T>> ด้วยการคลี่ฟิวเจอร์ที่ซ้อนกัน
// Wrong with thenApply — returns CF<CF<Order>>:
CompletableFuture<CompletableFuture<Order>> nested =
fetchUser(id).thenApply(u -> fetchLatestOrder(u.getId()));
// Correct with thenCompose — returns CF<Order>:
CompletableFuture<Order> flat =
fetchUser(id).thenCompose(u -> fetchLatestOrder(u.getId()));thenCompose สำหรับการเรียกแบบอะซิงก์ตามลำดับ
ใช้ thenCompose เมื่อแต่ละขั้นตอนแบบอะซิงก์ขึ้นอยู่กับผลลัพธ์ของขั้นตอนก่อนหน้า ทำให้ขั้นตอนต่าง ๆ ทำงานตามลำดับและขึ้นอยู่กับผลลัพธ์
fetchUser(userId)
.thenCompose(user -> fetchOrders(user.getId()))
.thenCompose(orders -> computeTotal(orders))
.thenAccept(total -> System.out.println("Total: " + total));thenApply เทียบกับ thenCompose
thenApply: แปลง T -> U (การแปลงแบบทำงานทันที) thenCompose: แปลง T -> CompletableFuture<U> แล้วคลี่ผลลัพธ์ ใช้ compose เมื่อขั้นตอนถัดไปเป็นงานแบบอะซิงก์เช่นกัน
การจัดการข้อผิดพลาดระหว่างทางด้วย handle
handle(BiFunction<T, Throwable, U>) จะถูกเรียกไม่ว่าฟิวเจอร์จะเสร็จสมบูรณ์ตามปกติหรือเกิดข้อผิดพลาด จึงสามารถกู้คืนหรือแปลงข้อผิดพลาดระหว่างกระบวนการทำงานได้
fetchUser(id)
.thenApply(User::getProfile)
.handle((profile, ex) -> {
if (ex != null) return Profile.empty(); // recover
return profile;
})
.thenAccept(System.out::println);whenComplete: ผลข้างเคียงหลังทุกผลลัพธ์
whenComplete(BiConsumer) จะถูกเรียกหลังการเสร็จสมบูรณ์ ไม่ว่าจะเป็นปกติหรือเกิดข้อผิดพลาด เพื่อบันทึกการทำงานหรือทำความสะอาดทรัพยากร ต่างจาก handle ตรงที่ไม่เปลี่ยนแปลงผลลัพธ์
fetchAsync()
.whenComplete((result, ex) -> {
if (ex != null) log.error("Failed", ex);
else log.info("Result: " + result);
});ตัวอย่างกระบวนการทำงานแบบไม่บล็อก
ประกอบกระบวนการทำงานที่ไม่บล็อกอย่างสมบูรณ์ ได้แก่ ดึงข้อมูลผู้ใช้ ดึงคำสั่งซื้อของผู้ใช้ และคำนวณสรุป โดยทุกขั้นตอนทำงานแบบอะซิงก์และแต่ละขั้นตอนขึ้นอยู่กับขั้นตอนก่อนหน้า
CompletableFuture<String> summary =
fetchUser(userId)
.thenCompose(u -> fetchOrders(u.getId()))
.thenApply(orders -> orders.size() + " orders")
.exceptionally(ex -> "Error: " + ex.getMessage());
System.out.println(summary.join());ตรวจสอบความเข้าใจ
ควรใช้ thenCompose แทน thenApply เมื่อใด
สรุปทบทวน
thenApply แปลงค่าแบบทำงานทันทีในกระบวนการทำงาน ส่วน thenCompose เชื่อมต่อขั้นตอนแบบอะซิงก์ (flatMap สำหรับฟิวเจอร์) และ handle / whenComplete เพิ่มการจัดการข้อผิดพลาดกับผลข้างเคียง ควรสร้างกระบวนการทำงานจากซ้ายไปขวาเพื่อให้อ่านง่าย
คำถามที่พบบ่อย
บทเรียน “การเชื่อมต่อด้วย thenApply และ thenCompose” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเชื่อมต่อด้วย thenApply และ thenCompose” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเชื่อมต่อด้วย thenApply และ thenCompose”
แปลงผลลัพธ์ด้วย thenApply และเชื่อมขั้นตอนอะซิงโครนัสแบบ flatMap ด้วย thenCompose เพื่อหลีกเลี่ยง future ซ้อนกัน คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การเชื่อมต่อด้วย thenApply และ thenCompose” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การสร้างและทำ CompletableFutures ให้เสร็จสมบูรณ์
- การเชื่อมต่อด้วย thenApply และ thenCompose
- การรวม Futures: allOf และ anyOf
- การจัดการข้อผิดพลาดและไปป์ไลน์ HTTP แบบอะซิงโครนัส