فراخوانی چند فانکشن متفاوت با تسک


#1

با درود خدمت دوستان گرامی . من سه تا فانکشن دارم که از هر تیبل مختلف اطلاعات رو می یارند.

به صورت مثال این

 def fn1(invoice_id)
  invoice_id + 1
 end

 def fn3(invoice_id)
  invoice_id + 1
 end

 def fn3(invoice_id)
  invoice_id + 1
 end

تاحالا تمام تسک هایی که درست می کردم این بود که یک تابع رو می بردم تو تسک و ورودی های مختلفی داشتم ولی الان ورودی یکی هست ولی خود فانکشن های استفاده شده در تسک متفاوت و من نیاز دارم این سه فانکشن لود بشه هر کدوم زودتر درست شد بره توی مپ و در آخر مپی که بهم داده می شه دارای سه خروجی باشه به صورت زیر مثلا

{fn1, fn2, fn3}

به روش قدیمی من مثلا به این صورت عمل می کردم

  def extera_finder(invoice_id) do
    Task.Supervisor.async WeddingCardWeb.AdminInvoicesController, fn ->
      function_name(invoice_id)
    end
  end

  def function_name(invoice_id) do
    :timer.sleep(100)
    invoice_id
    |> Enum.map(fn inv -> "by Shahryar tavakkoli #{inv}" end)
    |> IO.inspect
  end

این فانکشن عملیاتیم و تسکم هست و برای فراخوانیشم به این صورت

cities = ["Singapore", "Monaco", "Vatican City", "Hong Kong", "Macaus", "Amol","Tehran","Esfahan","Zanjan"]
WeddingCardWeb.AdminInvoicesController.extera_finder cities

خوب این دیگه برام کاربردی نداره من نیاز به این دارم که بیام سه فانکشن بدم که هر کدوم منتظر دیگری نمونه تا اطلاعات بیاره بلکه هر کدوم زودتر اومد بره تو مپ.

در رابطه با اینکه چرا از موارد بانک اطلاعاتی استفاده نمی کنم مثلا پریلود یا … باید بگم به دلایلی در حال یادگیری و بهبود خودم هست و ممکنه این فانکشن ها بعدا تبدیل به api یک وب سرویس خارجی بشند

پیشاپیش ممنونم


#2

میتونی یک لیست درست کنی که هرکدام یک تابع رو با یک تسک انجام بده بعد تمامه آنهارو مپ کنی به
Task.await

[Task.async(fn() -> IO.puts "hi" end), Task.async(fn() -> IO.puts "w" end)] 
|> Enum.map(&Task.await/1)

یک مثال از کده قبلی من

defmodule Blitzy.Worker do

  def make_http_requests(url, number_of_requests) do

    Enum.map(1..number_of_requests, fn i ->
      Task.Supervisor.async(Blitzy.TasksSupervisor,__MODULE__, :get_url,[url, i])
    end)

    |> Enum.map(&Task.await/1)
  end


  def get_url(url, i) do
    case HTTPoison.get(url) do
      {:ok, %HTTPoison.Response{status_code: status_code}} ->
        IO.puts "#{i}: #{status_code}"
      {:error, %HTTPoison.Error{reason: reason}} ->
        IO.inspect reason
    end
  end
end

در این مثال درخواست ها با ترتیب تمام شدن میان نه ترتیبی که در لیست اصلی هستند


#3

ممنون سام عزیز پس در حقیقت اینجا سه تا تسک در حال لود شدن هست درسته !! من فکر می کردم حتما باید در یک تسک بره و تو خودش بیام مپش کنم . ممنونم ازت ازش غول ساخته بودم فکرم کار نمی کرد

من کدمو با راهنمایی شما کمی بهبود دادم

  def test2 do
    [remover(:fn1), remover(:fn2), remover(:fn3)]
    |> Enum.map(&Task.await/1)
  end

  def remover(function_name) do
    Task.Supervisor.async(WeddingCardWeb.AdminInvoicesController,
      fn -> apply(WeddingCardWeb.AdminInvoicesController, function_name, [])
    end)
  end

#4

بله هر تابع که میخواهی در process جدا اجرا بشه باید اسم خودشو داشته باشه کد آخرت درسته
ولی یادت باشه که چون اینا async اجرا میشن لیست آخری به ترتیبه اجرا توابع برمیگرده و ترتیبه اولی را نداره


#5

ممنون سام عزیز بله براشون مثل مپ name تعریف کردم جابه جا هم بشند باز مشکلی ایجاد نمی کنند تشکر