ms-jpq / lua-async-await

Async Await in 90 lines of code.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot return functions in async methods

svermeulen opened this issue · comments

Using the implementation here, you cannot create async functions that return functions, since the returned functions will always be interpreted as a 'thunk'. I attempted to modify the pong method to allow this. In case it's useful to others, I wanted to share what I'm using instead:

local pong = function (func, callback)
  assert(type(func) == "function", "Expected type func but found " .. type(func))
  local thread = co.create(func)
  local step = nil
  step = function (...)
    local go, ret = co.resume(thread, ...)
    assert(go)
    if co.status(thread) == "dead" then
      if callback then
        callback(ret)
      end
    else
      assert(type(ret) == "function")
      ret(step)
    end
  end
  step()
end

This allows function return values because it always calls the callback value when the coroutine is dead. Also, I think we can assume that the go value is always true now that we are checking the co.status immediately after the call to resume

Thank you!

Really good catch, but by the looks of it doing this will swollow errors from coroutines.

When I have more time Ill try to figure out how to make it all work nicely :D

Sorry Ill leave this issue hanging for a bit, brain is foggy right now

Also you are from halifax!

ohhhhhhhhh canada, our home and native land.

Go Canada!

Haha, yes, I see you are a fellow canadian as well :)

Yes, you are correct. I realize now that go will be false when exceptions occur. I've now modified it to this instead:

local pong = function (func, callback)
  assert(type(func) == "function", "Expected type func but found " .. type(func))
  local thread = co.create(func)
  local step = nil
  step = function (...)
    local go, ret = co.resume(thread, ...)
    assert(go, "Async function failed! Details: " .. ret)
    if co.status(thread) == "dead" then
      if callback then
        callback(ret)
      end
    else
      assert(type(ret) == "function")
      ret(step)
    end
  end
  step()
end

i have update the code, thank you.

also added you to the read me #thank section 👍

local async_tasks_2 = function (val)
  return a.sync(function ()
    -- await all
    local w, z = a.wait_all{e2(val, val + 1), e2(val + 2, val + 3)}
    print(unpack(w))
    print(unpack(z))
    return function ()
      return 4
    end
  end)
end

the example code works with func returns