在过去的12个小时里,我一直在研究这个问题,而我似乎无法随时随地.我甚至都不知道这是否可能,但我希望这是因为继续我的项目会有很长的路要走.
我试图做的是创建协同程序,因此我使用的特定程序不会因为无法执行异步http请求而冻结.我已经想出了如何做到这一点,尽管我对协同程序的理解仍然在"嗯?这是如何工作的?" 相.我现在的问题是能够使用正确的信息响应多个请求.例如,以下内容应产生三个单独的响应:
foo(a)
foo(b)
foo(c)
Run Code Online (Sandbox Code Playgroud)
其中foo使用里面的参数启动协同程序.如果全部单独请求,则返回正确的结果.但是,如果作为块请求,它将仅返回foo(c)结果.现在,我理解这背后的原因,但是当我作为一个块请求时,我找不到让它返回所有三个结果的方法.为了帮助理解这个问题,这里是实际的代码:
function background_weather()
local loc = url.escape(querystring)
weatherpage = http.request("http://api.wunderground.com/api/004678614f27ceae/conditions/q/" .. loc .. ".json")
wresults = json.decode(weatherpage)
--process some stuff here, mainly datamining
end
--send datamined information as a response
coroutine.yield()
end
Run Code Online (Sandbox Code Playgroud)
和协程的创建:
function getweather ()
-- see if backgrounder running
if background_task == nil or
coroutine.status (background_task) == "dead" then
-- not running, create it
background_task = coroutine.create (background_weather)
-- make timer to keep it going
AddTimer ("tickler", 0, 0, 1, "",
timer_flag.Enabled + timer_flag.Replace,
"tickle_it")
end -- if
end -- function
Run Code Online (Sandbox Code Playgroud)
该querystring变量被设置与初始请求.我没有在这里包含它,但为了测试,使用它12345作为querystring变量.计时器是脚本的原始作者初始化以检查协程是否仍在运行的东西,每秒都会调整背景直到完成.说实话,我甚至不确定我是否已正确完成此操作,尽管它似乎在程序中异步运行.
那么,是否可以在一个块中接收多个请求并正确返回多个响应?或者这对Lua来说是一项太多的任务了?
协同程序不能那样工作.事实上,它们是封锁的.
协同程序解决的问题是"我想要一个我可以执行一段时间的函数,然后再回去做其他事情,然后回来并保持我离开时的状态".
请注意,我没有说"我希望它在我做其他事情时继续运行"; 代码流程在协程上"停止",并且只有当你返回它时才会继续.
使用协同程序,您可以修改(在某些情况下有助于)代码的行为方式,使其更明显或更清晰.但它仍然是严格的单线程.
请记住,Lua实现的必须由C99指定.由于此标准没有附带线程实现,因此默认情况下Lua严格是单线程的.如果您想要多线程,则需要将其挂钩到外部lib.例如,luvit将Luajit与libuv lib挂钩以实现此目的.
几个很好的参考: