Lua 忽略作用域变量
Lua ignoring scope variable
这可能是一个愚蠢的问题,但是,我不知道发生了什么。
我有一个获取 google 时间的简单脚本,我需要将它设置为 time
全局变量。因此,在 receive
事件中,我打印了获取的时间并且它正常工作。
问题是变量 time
在事件外部调用时总是为空。这是代码:
-- test.lua
time = ""
function getTime()
conn = net.createConnection(net.TCP, 0)
conn:connect(80,'google.com')
conn:on("connection", function(conn, payload)
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)
conn:on("receive", function(conn, payload)
conn:close()
time = string.sub(payload,string.find(payload,"Date: ")
+6,string.find(payload,"Date: ")+35)
end)
print("testing: " .. time) -- WORKS!
end
getTime()
print("variable: ".. time)
这是我调用该函数的方式(使用 nodemcu-uploader 终端):
➜ test nu terminal
--- Miniterm on /dev/cu.wchusbserial1410 115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
> dofile('lib/test.lua')
variable:
> testing: Sat, 20 May 2017 01:37:35 GMT
非常感谢任何帮助!
谢谢
看起来瞄准镜没问题。检查输出打印的顺序。
conn:connect
和 con:on
接受函数,因为它们是异步的。 getTime()
只是 returns 在它们被调用之前。
The NodeMCU programming model is similar to that of Node.js, only in Lua. It is asynchronous and event-driven. Many functions, therefore, have parameters for callback functions.
来源:https://github.com/nodemcu/nodemcu-firmware/#programming-model
这意味着接受回调函数作为参数的函数是非阻塞。它 return 意味着您不能只是逐行阅读一段代码并期望它按该顺序执行。
所以,你原程序的顺序大致是这样的:
getTime
被触发 但不阻止 .
print("variable: ".. time)
被执行。 time
此时还是空的。
- 与 google.com 的连接已建立。
- HEAD 请求发送到 google.com。
- 响应是接收和接收事件处理程序(即匿名回调函数)启动。
time
已填充。
我看到两个明显的修复,一个使用全局 time
变量,一个不使用。两者都基于传递回调函数作为参数模式。
请注意,您应该始终在 触发这些事件 (conn:connect
) 之前 设置事件侦听器(在您的情况下为 conn:on
)以避免丢失一些事件。你的代码
conn:connect(80,'google.com')
conn:on("connection"...
之所以有效,是因为 conn:connect
是非阻塞的,而且建立连接需要一些时间。当发生这种情况时,连接事件处理程序已经注册。
保持全局变量
time = ""
function getTime(cb)
conn = net.createConnection(net.TCP, 0)
conn:on("connection", function(socket, payload)
socket: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)
conn:on("receive", function(socket, payload)
socket:close()
time = string.sub(payload, string.find(payload, "Date: ")
+ 6, string.find(payload, "Date: ") + 35)
print("time inside on-receive: " .. time)
cb()
end)
conn:connect(80, 'google.com')
end
function do_something_with_time()
print("time inside callback: " .. time)
end
getTime(do_something_with_time)
没有全局变量
function getTime(cb)
conn = net.createConnection(net.TCP, 0)
conn:on("connection", function(socket, payload)
socket: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)
conn:on("receive", function(socket, payload)
socket:close()
local time = string.sub(payload, string.find(payload, "Date: ")
+ 6, string.find(payload, "Date: ") + 35)
print("time inside on-receive: " .. time)
cb(time)
end)
conn:connect(80, 'google.com')
end
function do_something_with_time(time)
print("time inside callback: " .. time)
end
getTime(do_something_with_time)
这可能是一个愚蠢的问题,但是,我不知道发生了什么。
我有一个获取 google 时间的简单脚本,我需要将它设置为 time
全局变量。因此,在 receive
事件中,我打印了获取的时间并且它正常工作。
问题是变量 time
在事件外部调用时总是为空。这是代码:
-- test.lua
time = ""
function getTime()
conn = net.createConnection(net.TCP, 0)
conn:connect(80,'google.com')
conn:on("connection", function(conn, payload)
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)
conn:on("receive", function(conn, payload)
conn:close()
time = string.sub(payload,string.find(payload,"Date: ")
+6,string.find(payload,"Date: ")+35)
end)
print("testing: " .. time) -- WORKS!
end
getTime()
print("variable: ".. time)
这是我调用该函数的方式(使用 nodemcu-uploader 终端):
➜ test nu terminal
--- Miniterm on /dev/cu.wchusbserial1410 115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
> dofile('lib/test.lua')
variable:
> testing: Sat, 20 May 2017 01:37:35 GMT
非常感谢任何帮助! 谢谢
看起来瞄准镜没问题。检查输出打印的顺序。
conn:connect
和 con:on
接受函数,因为它们是异步的。 getTime()
只是 returns 在它们被调用之前。
The NodeMCU programming model is similar to that of Node.js, only in Lua. It is asynchronous and event-driven. Many functions, therefore, have parameters for callback functions.
来源:https://github.com/nodemcu/nodemcu-firmware/#programming-model
这意味着接受回调函数作为参数的函数是非阻塞。它 return 意味着您不能只是逐行阅读一段代码并期望它按该顺序执行。
所以,你原程序的顺序大致是这样的:
getTime
被触发 但不阻止 .print("variable: ".. time)
被执行。time
此时还是空的。- 与 google.com 的连接已建立。
- HEAD 请求发送到 google.com。
- 响应是接收和接收事件处理程序(即匿名回调函数)启动。
time
已填充。
我看到两个明显的修复,一个使用全局 time
变量,一个不使用。两者都基于传递回调函数作为参数模式。
请注意,您应该始终在 触发这些事件 (conn:connect
) 之前 设置事件侦听器(在您的情况下为 conn:on
)以避免丢失一些事件。你的代码
conn:connect(80,'google.com')
conn:on("connection"...
之所以有效,是因为 conn:connect
是非阻塞的,而且建立连接需要一些时间。当发生这种情况时,连接事件处理程序已经注册。
保持全局变量
time = ""
function getTime(cb)
conn = net.createConnection(net.TCP, 0)
conn:on("connection", function(socket, payload)
socket: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)
conn:on("receive", function(socket, payload)
socket:close()
time = string.sub(payload, string.find(payload, "Date: ")
+ 6, string.find(payload, "Date: ") + 35)
print("time inside on-receive: " .. time)
cb()
end)
conn:connect(80, 'google.com')
end
function do_something_with_time()
print("time inside callback: " .. time)
end
getTime(do_something_with_time)
没有全局变量
function getTime(cb)
conn = net.createConnection(net.TCP, 0)
conn:on("connection", function(socket, payload)
socket: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)
conn:on("receive", function(socket, payload)
socket:close()
local time = string.sub(payload, string.find(payload, "Date: ")
+ 6, string.find(payload, "Date: ") + 35)
print("time inside on-receive: " .. time)
cb(time)
end)
conn:connect(80, 'google.com')
end
function do_something_with_time(time)
print("time inside callback: " .. time)
end
getTime(do_something_with_time)