2017-05-20 7 views
3

이것은 어리석은 질문 일지 모르지만, 나는 어떤 일이 일어나고 있는지 모른다.범위 변수를 무시하는 루아

저는 간단한 스크립트를 사용하여 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 - 업 로더 터미널을 사용) 함수를 호출하고있어 방법은 다음과 같습니다

➜ 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 

어떤 도움이 정말 감사하겠습니다! 감사합니다.

+0

조심해! 이것은'connection'과'receive' 콜백에서'conn' 변수를 다시 사용하기 때문에 메모리 누수를 만듭니다. http://stackoverflow.com/a/37379426/131929를 참조하십시오. –

+0

@ MarcelStör .. 이벤트가 끝나면 'nil'로 설정하면 해결할 수 있습니까? – hugalves

답변

1

NodeMCU 프로그래밍 모델은 Node.js와 유사하지만 Lua에만 있습니다. 비동기식이며 이벤트 중심입니다. 따라서 많은 함수에는 콜백 함수에 대한 매개 변수가 있습니다.

자료 : https://github.com/nodemcu/nodemcu-firmware/#programming-model 파라미터 그대로 콜백 함수를 접수 기능 비를 차단한다는 것을 의미

. 반환한다는 것은 한 줄의 코드를 한 줄씩 읽고 그 순서대로 실행될 것을 기대할 수 없다는 것을 의미합니다.

그래서, 원래 프로그램에서 이벤트의 순서는 대략 이것이다 :

  • getTime를 트리거하지만을 차단하지 않습니다.
  • print("variable: ".. time)이 실행됩니다. 이 시점에서 time은 여전히 ​​비어 있습니다.
  • google.com에 연결되었습니다.
  • HEAD 요청은 google.com으로 전송됩니다.
  • 응답은 수신 및 수신 이벤트 핸들러 (즉, 익명 콜백 함수)가 시작됩니다.
  • time이 채워집니다.

글로벌 time 변수를 사용하는 것과 그렇지 않은 것이있는 두 가지 명백한 수정 사항이 있습니다. 둘 다 통과 콜백 기능 매개 변수 패턴을 기반으로합니다. 당신은 항상 (귀하의 경우 conn:on를) 이벤트 리스너를 설정해야합니다

전에 해당 이벤트는 일부 이벤트 누락 방지하기 위해 (conn:connect) 트리거됩니다.귀하의 코드

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) 
+0

DAAAAMN !! 너 락! 나는 완전히 이해했다! 대단히 감사합니다 !! – hugalves

2

범위가 괜찮은 것 같습니다. 출력물이 인쇄하는 순서를 확인하십시오.

conn:connectcon:on은 비동기이기 때문에 함수를 사용합니다. getTime()은 호출되기 전에 단순히 반환됩니다.

+0

나는 이것을 알지 못했다. 이것을 처리 할 제안이 있습니까? 자다? – hugalves

+1

@hugalves 가장 간단한 방법은 getTime에 함수를 전달하고 시간을 설정하는 대신 호출하는 것입니다. 이 기능을 사용하면 시간을 설정하고 인쇄 할 수 있습니다. 그러나 당신의 프로그램은 그보다 더 복잡 할 수 있습니다. –

+1

내 제안은 이벤트 기반 프로그래밍을 배우는 것입니다. 신호와 이벤트를 사용하면 코드/장치의 응답 성이 향상됩니다. 차단하면 나쁜 일이 일어납니다. FAQ를 읽으십시오 : https://nodemcu.readthedocs.io/en/master/en/lua-developer-faq/ –