A simple way to turn callback pattern to coroutine pattern in Lua
My game project is written by Lua. However, its framework does not provide a coroutine pattern, it uses a simple callback pattern instead. For example, to send an http request and receive the response, you must write like this:
1 |
|
For simple requests, it’ OK. However, in some scenarios, maybe there are several successive requests in one procedure. For example, you must request A and then request B, and then request C. It makes you fall in the callback hell. Worse yet, sometimes you should call A again if request C fails. As we all know, coroutines can resolve this problem easily, but how can we use coroutines without changing the framework? Inspired by Javascript’s Promise, I found an easy way to turn callback pattern to coroutine pattern. Review how JS’s Promise is made:
1 |
|
JS can await for a Promise object and then suspend the coroutine. After calling resolve
, the coroutine resumes. That’s a good idea but I don’t need a Promise object since I dont’t need so many methods like then
and catch
. So I decided to implement a simple mechanism.
The key is we should suspend the coroutine and resume it after calling the callback resolve
. Therefore, instead of yield an object, we can just yield a function whose parameter is the callback function resolve
. We pass the resolve
function to the yielded function after the coroutine suspended. In the resolve
function, we resume the coroutine and pass its parameters to the coroutine, so the coroutine will be resumed after calling the resolve
function. The code is as follows:
1 |
|
Well, it’s a very simple implementation. No such sophisticated mechanism as JS’s Promise, but it works well! You can use it like this:
1 |
|
It’s easy for several successive requests too. You can also encapsulate a function suitable for coroutines. Here is a complex example that is hard to write in callback pattern:
1 |
|