วันนี้ได้มีโอกาสไปงาน 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
จริงๆแล้ว Elixir/Erlang ยังมีอีกหลายท่าที่ช่วยให้เราจัดการ Asynchronous Task ได้ง่ายๆ ซึ่งทางคุณ Zack เองก็เอามาให้ดูหลายท่า เดี๋ยวผมจะสรุปอีกทีใน post ถัด ๆ ไปครับ
Top comments (2)
ผมสงสัยตั้งแต่ว่า Erlang/Elixir ต้องใช้ async-await เมื่อไหร่ครับ ? ใช้เวลา spawn หลาย ๆ process แล้วมารอทีเดียวแบบนั้นเปล่าครับ ? หรือ async ไม่ต้อง spawn process ใหม่เลย ?
จริงๆด้านในคือใช้ฟีเจอร์ process ของ Erlang VM นั่นแหละครับ แต่ทำมาให้แล้ว ไม่ต้องเขียนจัดการ message passing เอง