Hi everyone. I think I am missing about understanding how coroutines work.
I have searched forum and found some examples, but still could not make code work synchronously.
local co = coroutine.create(function()
local co = coroutine.running()
print('request is executed')
http.request("http://d.defold.com/stable/info.json", "GET", function(self, id, response)
print('result is fetched')
coroutine.resume(co, response)
end)
return coroutine.yield()
end)
local ok, err = coroutine.resume(co)
print('should not be executed before fetched result')
From my understand last print(âshould not be executedâŚâ) should printed last, since we are pausing coroutine until we receive response from the http request. But it does not work like this.
The output, which I get is:
DEBUG:SCRIPT: request is executed
DEBUG:SCRIPT: should not be executed before fetched result
DEBUG:SCRIPT: result is fetched
It is the code within the coroutine that doesnât continue to execute. In this case as soon as you yield you give back control to the main thread and the print() will be executed.
The correct code would be:
local function http_request(url, method)
local co = coroutine.running()
http.request("http://d.defold.com/stable/info.json", "GET", function(self, id, response)
print('result is fetched')
coroutine.resume(co, response)
end)
return coroutine.yield()
end
local co = coroutine.create(function()
print('request is executed')
local response = http_request("http://d.defold.com/stable/info.json", "GET")
print('should not be executed before fetched result')
end)
local ok, err = coroutine.resume(co)
Sorry, but still not very clear for me. If I will add print after âlocal ok, err = coroutine.resume(co)â, then it will be executed before result is fetched.
1 - We start the coroutine. The current âthreadâ (main) is paused when coroutine.resume() is called and we start execution of the coroutine function. The text ârequest is executedâ is printed.
2 - We call the http_request() function which in turn calls the http.request() function. The call to http.request() is asynchronous and the callback doesnât get immediately invoked.
3 - We proceed to call coroutine.yield(). This pauses the coroutine and returns control to the main âthreadâ. The text âfoobarâ is printed.
âŚ
4 - Sometime later the call to http.request() is completed and the http.request() callback function is invoked. The text âresult is fetchedâ is printed.
5 - The coroutine is resumed from the point in http_request where we called coroutine.yield(). Execution on the main âthreadâ is again paused. We end up on the line after the call to http_request and the text âshould not be executed before fetched resultâ is printed. This is the last line of code in the coroutine function and the coroutine has now finished running.
Thank you very much for such detailed answer, but my idea was exactly to pause main thread until we get some results from http_request, so we can work with response in main thread synchronously.
Well, the async operation and the processing of the response has to be in the same coroutine. If you pause or block the main thread the whole engine will be affected.
Then here comes some message listener in place. I guess, I have thought of not correct design in the first place. Thank you for your responses, they are very valuable!