nim-lang / RFCs

A repository for your Nim proposals.
135 stars 26 forks source link

Few ideas for the asyncdispatch module #458

Closed archnim closed 1 year ago

archnim commented 2 years ago

Hello world. What do you think about adding these few templates:

myFuture.callback = cb

We could write:
```nim
myFuture.then:
  # To do when future succeeds
myFuture.catch:
  # To do when future fails
myFuture.finally:
  # To do in any case
dom96 commented 2 years ago

it would be nice to replicate the APIs that other languages have on futures, for example JS.

juancarlospaco commented 2 years ago

Theres then and catch already, used in jsfetch. Theres once already https://nim-lang.github.io/Nim/system.html#once.t%2Cuntyped

archnim commented 2 years ago

Thank you Juancarlos. I propose that then and catch can be used in other contexts too. Concerning once, it exists, but for another purpose than the one that I suggest here. So we can imagine another name for "my own" once. Maybe asa ? Which would stand for "as soon as"...

asa myCondition:
  # things to do
juancarlospaco commented 2 years ago

I agree with improving and expanding the existing once, then, catch to all targets.

juancarlospaco commented 2 years ago

I do not like the name asa.

archnim commented 2 years ago

I don't like "asa" that much either. I just lack inspiration.

We should also add async versions of procs and templates dealing with locks. For example, a non blocking version of withlock.

archnim commented 1 year ago

Here is an attempt of implementation of once .

I also use the opportunity to introduce a template named doAfter, which shedules a background operation for later (Like setTimeout in Js). So we can now write:

doAfter 5_000: echo "Five seconds pasted !"
archnim commented 1 year ago
import asyncdispatch

proc doAfter*(ms: int or float, todo: proc() {.closure.}) =
  proc p () {.async.} =       # An inner async proc so that the main
    await sleepAsync(ms)      # proc will not return a future
    todo()

  discard p()

template once*(cond: bool, todo: untyped) =
  let p = proc () {.async.} =  # is a variable so it remains local to the template
    while not cond:
      await sleepAsync(5) # Maybe not the best way 🤷🏽‍♂️
    todo

  discard p()
archnim commented 1 year ago

So what do you think about doAfter ? What about its name ?

I deliberately wrote doAfter as a proc and once as a template. I would like to know your opinion about which approach is the best in this case ?

Should I also create a version of doAfter that returns a handle to manage the timeout ?

And finally in which file should I write it, especially to fit V2's file reorganization ? 'asyncdispatch.nim' right ?

archnim commented 1 year ago

Just a runnable example:

var c = false

once c :
  echo "It's true ! 😃😜🤪"

doAfter 3_000:
  c = true

waitFor sleepAsync 4_000 # For the process to wait for the end of the test