Now there is another problem. I hope I can write the code like this: proc ff1(p1: int): Result = # my db acess code here ...... proc ff2(p1, p2: int): Result = # my db acess code here ...... proc main() {.async.} = # async call ff1 with parameter let r1 = await callAsync(ff1(1)) # async call ff2 with parameter let r2 = await callAsync(ff2(1, 2)) ......
Because we pass the parameter 'ff1(1)' to callAsync, so callAsync must be a macro like this: macro callAsync*(p: untyped): untyped {.async.} = quote do: proc callme(evt: AsyncEvent): Result = let s = `p` evt.trigger() s let evt = newAsyncEvent() let fut = waitEvent(evt) let val = spawn callme(evt) await fut return ^val But a macro cannot be {.async.}, so I cannot do this. A limited way to resolve this problem is use an procval, here is the code: type Result* = ref object of RootObj body*: string Action = proc(): Result proc waitEvent(evt: AsyncEvent): Future[void] = let fut = newFuture[void]("callAsync") addEvent(evt, (fd: AsyncFD) => (fut.complete(); true)) return fut proc callp(evt: AsyncEvent, p: Action): Result = let v = p() evt.trigger() v proc callAsync*(p: Action): Future[Result] {.async.} = let evt = newAsyncEvent() let fut = waitEvent(evt) let val = spawn callp(evt, p) await fut return ^val proc ff(): Result = echo "work" sleep(1000) Result(body: "hello") block: let val = waitFor callAsync(ff) echo "future return ", val.body The limitation is I can only call Action type proc, and I cannot pass the paramter freely. Any way to solve the problem? Thanks.