0Pricing
Scala for Backend Engineering & Functional Programming · บทเรียน

การประกอบการดำเนินการแบบอะซิงโครนัส

เรียนรู้การเชื่อมโยงและรวม `Futures` หลายรายการโดยใช้เมธอดอย่าง `map`, `flatMap` และนิพจน์ `for`

การประกอบการดำเนินการแบบอะซิงโครนัส เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 3 บทเรียน

เหตุใดจึงต้องเชื่อมโยงการทำงานแบบอะซิงโครนัส

Future ช่วยให้เราเรียกใช้งานต่าง ๆ ได้โดยไม่บล็อกโปรแกรมหลัก แต่หากต้องใช้ผลลัพธ์ของงานหนึ่งกับอีกงานหนึ่ง หรือจำเป็นต้องรวมผลลัพธ์จากหลายงานเข้าด้วยกัน จะทำอย่างไรดีครับ

การประกอบ Future เข้าด้วยกันมีประโยชน์ในกรณีนี้ เราจะเรียนรู้วิธีเชื่อมโยงและรวมการทำงานแบบอะซิงโครนัสเหล่านี้ เพื่อให้โค้ด Scala ของคุณมีประสิทธิภาพและตอบสนองได้ดียิ่งขึ้น

`map`: แปลงผลลัพธ์ของ Future

เมธอด map ใช้เมื่อคุณมี Future และต้องการแปลงผลลัพธ์ที่สำเร็จแล้วเป็นค่าอื่น ฟังก์ชันแปลงค่าที่คุณระบุจะถูกนำไปใช้เมื่อ Future ทำงานเสร็จสมบูรณ์

  • เมธอดนี้จะคืนค่าเป็น Future ใหม่เสมอ
  • เหมาะอย่างยิ่งสำหรับการแปลงผลลัพธ์แบบง่าย ๆ ที่ทำงานพร้อมกันทันที

การใช้งาน `map` (โค้ด)

ในตัวอย่างนี้ เรารับตัวเลขจาก Future แล้วคูณตัวเลขนั้นด้วยสองโดยใช้ map การแปลงค่าจะเกิดขึ้นหลังจาก Future เริ่มต้นทำงานเสร็จแล้วเท่านั้น

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

object Main {
  def main(args: Array[String]): Unit = {
    val originalFuture: Future[Int] = Future {
      Thread.sleep(100) // Simulate work
      10
    }

    val doubledFuture: Future[Int] = originalFuture.map(value => value * 2)

    val result = Await.result(doubledFuture, 1.second)
    println(s"Doubled value: $result")
  }
}

`flatMap`: เชื่อมโยง Future

บางครั้งผลลัพธ์ที่สำเร็จของ Future หนึ่งรายการต้องถูกนำไปเริ่มต้น Future อีกรายการหนึ่ง นี่คือจุดที่ flatMap มีประโยชน์ เมธอดนี้จะ "คลี่" Future ที่ห่อหุ้ม Future อีกชั้นหนึ่ง (Future[Future[T]]) ให้กลายเป็น Future[T] เพียงรายการเดียว

  • ใช้เมื่อฟังก์ชันแปลงค่าของคุณคืนค่าเป็น Future
  • จำเป็นสำหรับการทำงานแบบอะซิงโครนัสตามลำดับ

การใช้งาน `flatMap` (โค้ด)

เราดึงรหัสผู้ใช้ก่อน จากนั้นใช้รหัสดังกล่าวเพื่อดึงรายละเอียดผู้ใช้ แต่ละขั้นตอนเป็นการทำงานแบบอะซิงโครนัสที่คืนค่าเป็น Future และ flatMap ช่วยให้ขั้นตอนเหล่านี้ทำงานตามลำดับ

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

object Main {
  def main(args: Array[String]): Unit = {
    def fetchUserId(): Future[Int] = Future {
      Thread.sleep(50)
      123
    }

    def fetchUserDetails(userId: Int): Future[String] = Future {
      Thread.sleep(100)
      s"User $userId details"
    }

    val userDetailsFuture: Future[String] = fetchUserId().flatMap { userId =>
      fetchUserDetails(userId)
    }

    val result = Await.result(userDetailsFuture, 1.second)
    println(s"Details: $result")
  }
}

`map` กับ `flatMap`: ความแตกต่างสำคัญ

ผู้เรียนมักสับสนระหว่าง map และ flatMap โปรดจำไว้ดังนี้:

  • map: ฟังก์ชันของคุณคืนค่าเป็นค่าทั่วไป เช่น Int หรือ String ดังนั้น Future[A].map(A => B) จะได้ผลลัพธ์เป็น Future[B]
  • flatMap: ฟังก์ชันของคุณคืนค่าเป็น Future อีกตัวหนึ่ง เช่น Future[Int] หรือ Future[String] ดังนั้น Future[A].flatMap(A => Future[B]) จะได้ผลลัพธ์เป็น Future[B]

flatMap ใช้สำหรับเชื่อมโยงการทำงานแบบอะซิงโครนัส ส่วน map ใช้สำหรับแปลงผลลัพธ์อะซิงโครนัสแบบทำงานทันที

นิพจน์ `for`: การเชื่อมโยงอย่างกระชับ

นิพจน์ for ของ Scala มีรูปแบบไวยากรณ์ที่สะอาดตาและอ่านง่ายสำหรับเชื่อมโยงการทำงานที่ใช้ map และ flatMap นิพจน์เหล่านี้เป็นเพียงน้ำตาลทางไวยากรณ์ กล่าวคือคอมไพเลอร์จะแปลงนิพจน์เหล่านี้เป็นการเรียกใช้ map, flatMap และ filter ต่อเนื่องกัน

เมื่อมีการทำงานของ Future หลายรายการที่ขึ้นต่อกัน นิพจน์ for จะทำให้โค้ดดูเกือบเหมือนการทำงานแบบปกติ

โค้ดนิพจน์ `for`

ตัวอย่างนี้ใช้นิพจน์ for เพื่อเชื่อมโยงตรรกะการดึงรหัสผู้ใช้และรายละเอียดผู้ใช้แบบเดียวกับที่เราเห็นใน flatMap สังเกตไหมครับว่าโค้ดดูสะอาดตาขึ้นมาก

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

object Main {
  def main(args: Array[String]): Unit = {
    def fetchUserId(): Future[Int] = Future {
      Thread.sleep(50)
      123
    }

    def fetchUserName(userId: Int): Future[String] = Future {
      Thread.sleep(100)
      s"Alice (ID: $userId)"
    }

    val userFuture: Future[String] = for {
      id <- fetchUserId()
      name <- fetchUserName(id)
    } yield name

    val result = Await.result(userFuture, 1.second)
    println(s"User name: $result")
  }
}

`zip`: รวมผลลัพธ์ที่ไม่ขึ้นต่อกัน

หากคุณมี Future สองรายการที่ไม่ขึ้นต่อกันและต้องการรวมผลลัพธ์เมื่อทั้งสองรายการทำงานเสร็จแล้ว เมธอด zip เหมาะสำหรับกรณีนี้ เมธอดนี้รับ Future อีกตัวหนึ่งและคืนค่าเป็น Future ใหม่ที่เก็บคู่ข้อมูล (Tuple) ซึ่งประกอบด้วยผลลัพธ์ที่สำเร็จของทั้งสองรายการ

Future ทั้งสองรายการจะทำงานพร้อมกัน และ zip จะรอจนกว่าทั้งสองรายการจะทำงานเสร็จ

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

object Main {
  def main(args: Array[String]): Unit = {
    val futureA = Future {
      Thread.sleep(100)
      "Hello"
    }

    val futureB = Future {
      Thread.sleep(50)
      "World"
    }

    val combinedFuture: Future[(String, String)] = futureA.zip(futureB)

    val (greeting, subject) = Await.result(combinedFuture, 1.second)
    println(s"$greeting $subject!")
  }
}

ตรวจสอบความเข้าใจอย่างรวดเร็ว: การประกอบ Future

พิจารณาข้อมูลโค้ด Scala ต่อไปนี้ ค่าท้ายสุดที่พิมพ์ออกมาจะเป็นอะไรครับ

import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

object Main {
  def main(args: Array[String]): Unit = {
    val f1 = Future { 5 }
    val f2 = f1.map(x => x + 2)
    val f3 = f2.flatMap(y => Future { y * 3 })

    val result = Await.result(f3, 1.second)
    println(result)
  }
}

ทบทวน: การเชื่อมโยงงานแบบอะซิงโครนัส

คุณได้เรียนรู้วิธีที่มีประสิทธิภาพในการประกอบ Future ของ Scala ดังนี้:

  • map: แปลงผลลัพธ์ที่สำเร็จของ Future เป็นค่าใหม่
  • flatMap: เชื่อมโยง Future สองรายการ โดยใช้ผลลัพธ์ของรายการแรกเพื่อเริ่มรายการที่สอง
  • นิพจน์ for: มีไวยากรณ์ที่สะอาดและดูคล้ายการทำงานแบบปกติสำหรับการเชื่อมโยง flatMap และ map
  • zip: รวมผลลัพธ์ของ Future สองรายการที่ไม่ขึ้นต่อกันเป็นทูเพิล

เครื่องมือเหล่านี้จำเป็นอย่างยิ่งต่อการสร้างแอปพลิเคชันแบบอะซิงโครนัสใน Scala ที่ตอบสนองได้ดีและมีประสิทธิภาพ

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

บทเรียน “การประกอบการดำเนินการแบบอะซิงโครนัส” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การประกอบการดำเนินการแบบอะซิงโครนัส” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 3 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การประกอบการดำเนินการแบบอะซิงโครนัส”

เรียนรู้การเชื่อมโยงและรวม `Futures` หลายรายการโดยใช้เมธอดอย่าง `map`, `flatMap` และนิพจน์ `for` คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน

บทเรียน “การประกอบการดำเนินการแบบอะซิงโครนัส” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม

ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. บทนำสู่ Futures และ Promises
  2. การประกอบการดำเนินการแบบอะซิงโครนัส
  3. การจัดการข้อผิดพลาดใน Futures
← กลับไปที่ Scala for Backend Engineering & Functional Programming