DEV Community

Weerasak Chongnguluam
Weerasak Chongnguluam

Posted on

Elixir run asynchronous function with Task.async and Task.await

Alt Text

วันนี้ได้มีโอกาสไปงาน Elixir Casually Mini-meetup มา เป็นงาน meet-up เล็กๆ สำหรับกลุ่มคนใช้ Elixir ในไทย และ คนที่สนใจ

ซึ่ง session แรกได้ทางคุณ Zack Siri มาเล่าท่าต่าง ๆ ในการรัน asynchronous function ด้วย Elixir

สำหรับท่าแรกที่ง่าย ๆ เลยที่ผมเอามาสรุปวันนี้คือใช้ฟังก์ชัน Task.async (สำหรับใครที่ไม่เคยใช้ Elixir เวลาเห็น Task.async นั้น async เป็นชื่อฟังก์ชัน ที่อยู่ใน module Task เวลาใช้งานต้องเอาชื่อ module ก่อนแล้วค่อย dot ตามด้วยชื่อฟังก์ชันที่เราจะเรียกใช้ที่อยู่ใน module นั้น ๆ)

ซึ่งวิธีใช้งานคือเราจะส่งฟังก์ชันไปให้ Task.async ทำงาน เสร็จแล้วเราจะได้ค่าของ Task struct กลับออกมา เมื่อถึงจุดที่เราอยากได้ผลลัพธ์การทำงาน ก็ให้เราเรียกฟังก์ชัน Task.await พร้อมส่งค่าของ Task struct ไปให้ ก็จะได้ผลลัพธ์ของ Task นั้นที่เราสั่งไปรันผ่าน Task.async กลับมานั่นเอง

ตัวอย่างเช่น ผมจะเรียกใช้ :httpc.request ซึ่งเป็น function ในการสั่ง http request โดยให้ทำงานผ่าน Task.async แล้วค่อยเรียก Task.await ได้ดังนี้

# start :inets and :ssl for using :httpc 
# These modules from Erlang for make a http request
Application.ensure_all_started(:inets) 
Application.ensure_all_started(:ssl)

task = Task.async(fn ->
    :httpc.request('https://google.com')
end)

{:ok, {_, _, body}} = Task.await(task)

IO.puts body
Enter fullscreen mode Exit fullscreen mode

Alt Text

จริงๆแล้ว Elixir/Erlang ยังมีอีกหลายท่าที่ช่วยให้เราจัดการ Asynchronous Task ได้ง่ายๆ ซึ่งทางคุณ Zack เองก็เอามาให้ดูหลายท่า เดี๋ยวผมจะสรุปอีกทีใน post ถัด ๆ ไปครับ

Top comments (2)

Collapse
 
veer66 profile image
Vee Satayamas

ผมสงสัยตั้งแต่ว่า Erlang/Elixir ต้องใช้ async-await เมื่อไหร่ครับ ? ใช้เวลา spawn หลาย ๆ process แล้วมารอทีเดียวแบบนั้นเปล่าครับ ? หรือ async ไม่ต้อง spawn process ใหม่เลย ?

Collapse
 
iporsut profile image
Weerasak Chongnguluam

จริงๆด้านในคือใช้ฟีเจอร์ process ของ Erlang VM นั่นแหละครับ แต่ทำมาให้แล้ว ไม่ต้องเขียนจัดการ message passing เอง