Lua脚本没有按顺序执行

标签 lua esp8266 nodemcu esplorer

我想使用带有 NodeMCU 的 EPS8266 通过 I2C 设置 RTC。

这是我的脚本:

-- file print.lua     
local file = assert(loadfile("httpget.lua"))    
file()                  --get Date and Time from google    
print("Print follows:") --this should be executed after "file()"    
print(date)

这是文件httpget.lua:

-- file httpget.lua
print('httpget.lua started')
conn=net.createConnection(net.TCP, 0)
-- show the retrieved web page
conn:on("receive", function(conn, payload) 
                     date = string.sub(payload,string.find(payload,"Date: ")
                     +6,string.find(payload,"Date: ")+35)
                     conn:close()
                     end) 

conn:on("connection", function(conn, payload) 
                       print('\nConnected') 
                       conn:send("HEAD /  HTTP/1.1\r\n" 
                        .."Host: google.com\r\n" 
                        .."Accept: */*\r\n" 
                        .."User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)"
                        .."\r\n\r\n")
                        end)

-- when disconnected, let it be known
conn:on("disconnection", function(conn, payload)
                         print("Disconnected\r\n"..date)
                         end)                                             
conn:connect(80,'google.com')
conn = nil

结果是:

> dofile("print.lua")
httpget.lua started
Print follows:              -- this should be at the end
nil                         -- date==nil because httpget.lua not executed
> 
Connected
Disconnected
Sun, 26 Apr 2015 10:30:03 GMT

如果我再次执行 scipt(不重置),我会从之前的执行中获取日期。 我该怎么做才能执行“httpget.lua”并获取后面脚本中的“日期”?

我使用的是 ESP8266,其 NodeMCU 0.9.6 版本为 20150406,由 Lua 5.1.4 提供支持。 https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en#index

我使用 ESPlorer v2.0 通过 USB 将脚本加载到我的 ESP8266。 conn.net... 命令是 NodeMCU 固件的一部分(请参阅链接)。您只能使用 EPS8288 和 NodeMCU 固件运行该脚本。我的问题是:我找不到正确结束 conn:net 例程并将数据返回到下一个程序部分的方法。

最佳答案

正如评论者指出的那样,网络代码将异步运行,即 conn:on 调用将立即返回,并在稍后调用它们的回调。 conn:connect 调用可能不是异步的,但这没有帮助。

conn:connect 调用完成后,您的 print 调用将立即运行,尝试打印全局变量date。大多数情况下,这将打印nil,因为从Google获取数据的网络延迟将在>10毫秒内,这意味着您的代码已经有足够的时间来执行打印语句。在极少数情况下,如果您对网络延迟非常幸运的话,您实际上可能会获得正确的日期(尽管这会非常令人惊讶)。

要解决此问题,您需要将网络请求完成时要执行的代码放在传递给接收数据的 conn:on 的回调中。不过,在您当前的代码结构中,以良好的方式做到这一点有点困难。

一个简单的解决方案是:

local function onReceiveCb(str)
 print("Print follows:")
 print(str)
end
local file = assert(loadfile("httpget.lua"))
....

请注意,我在包含 httpget 代码之前添加了一个 onReceiveCb 函数。在 httpget 中调用回调:

conn:on("receive", function(conn, payload) 
                     date = string.sub(payload,string.find(payload,"Date: ")
                     +6,string.find(payload,"Date: ")+35)
                     conn:close()
                     onReceiveCb(date) -- Call the callback!
                     end) 

关于Lua脚本没有按顺序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29877118/

相关文章:

共享对象的lua加载路径

list - 迭代列表的特定条目

c - 无法使用 ESP8266 上传 HTML 页面

lua - 使用 nodeMCU 的 Wifi 网状网络

arduino - 如何使用esp8266将Arduino连接到pubnub云?

ssl - Lua SSL 证书和 Azure Iot 中心

io - Lua: io.read() 不适用于长字符串

lua - 我应该在lua中将函数中的变量定义为局部变量吗

ios - NodeMCU ESP8266 使用 C 连接到 iPhone 热点

azure - HTTPS 到 HTTP Azure IoT 中心