-
Notifications
You must be signed in to change notification settings - Fork 530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bring back IO#runAsync and friends? #2530
Comments
Hi 👋! Thanks for raising this issue. Have you tried using the Do report if this method is helpful, otherwise we can look for a new feature request. |
@vasilmkd Yes, I did try But it doesn't matter much; running an I'm using scalajs-react, which supports |
@matil019 I think @vasilmkd is right, actually
That's right, except the IO(step1()) *> IO(step2()) *> IO(step3()).start using Personally I think that having to do these two steps is cumbersome which is why I proposed #2478. |
I would appreciate it very much if @japgolly can use their knowledge of the This is a genuine question. I would like to know exactly how the definition def onClick(e: org.scalajs.dom.Event): IO[Unit] is supposed to function as an Thanks in advance. |
The only way I can see this happening if the React interop looks like this (excuse the hand wavy syntax): function somewhereInReact(event) {
const io = SomewhereInScala.onClick(event)
io.unsafeRunAndForget()
} And the only reason why So, in a sense, the library relies that this method of execution is used. This isn't a problem per se, we just maybe have to include Edit: |
Hey @vasilmkd , sorry I missed your question here. We don't have One could write const run = ...
const io = IO(println("hello"))
<button onClick={() => run(io)} /> So to work backwards:
|
scalajs-react also directly accepts |
@japgolly Thanks for going into detail. Can you maybe confirm then that the default implementation of |
It's up to users wrap |
Oh and btw, I'd be very happy to change scalajs-react if there's a better way to execute these effects. It would be a binary-compatible change so np, just let me know |
@japgolly Can users write an |
I think if you want your |
Actually if you change action.syncStep.unsafeRunSync().fold(_.unsafeRunAndForget(), _ => ()) What we're kind of getting at is whether or not this should be made more convenient. |
Right, I very much support this, but IMO the logic cuts both ways. If people want to execute something synchronously, they should really be reaching for |
@djspiewak except of course the danger of that is that is that we no longer have auto-yielding. Which might not be important for most uses as you say. |
Yes, except how do you combine both? Say you want to do |
I typically use |
Hot take: A mix of synchronous and asynchronous execution is what I'm naming "synchronously starting the execution of an asynchronous effect", which is exactly Daniel's code action.syncStep.unsafeRunSync().fold(_.unsafeRunAndForget(), _ => ()) and its type is |
Anything else is relying on implementation details. |
What if we added a step limiter overload to |
I think it needs some rearranging to get that type, but it can only become
Yes, I like this idea 👍 |
Yeah, the think the detail and new approach is fine. Also, as an end-user without very detailed knowledge of CE, I personally think it'd be pretty cool to have a method that wraps |
And we come full circle 😉 that's what I proposed in #2478. |
I'm not against a convenience method for this. I much prefer it over changing the execution model of |
I'd like to also use Daniels step-limiter idea, and ideally the convenience method can just grab it from it the |
The convenience method is just a little scary because it's so profoundly different from the normal execution approach. Not saying it's a wrong thing to do, it's just really really different and it feels better to make it explicit so users can't get into this mode by accident. |
I think it is much more dangerous on JVM than JS, and that's why I proposed we make the convenience method JS only. |
|
What about |
I do like that one :) in any case, it will need docs! |
Not every
Sorry I should have mentioned this earlier but I was reluctant to create a complete example, but I didn't want to miss the discussion here. |
@matil019 how long is |
@armanbilge its length is the number of items dragged and dropped so it's variable. I experienced the problem even if the length is only 1. If this relevant: I used to add Stream.range(0, dataTransfer.items.length)
.map(i => dataTransfer.items(i))
.evalMap(item => IO(item.getAsFileSystemHandle().toFuture))
.bufferAll
.evalMap(fut => IO.fromFuture(IO(fut)))
// map, flatMap, etc. That said, if auto-yielding is a thing, I don't see the point of EDIT: Does |
Thanks for the details! Not immediately clear to me why it's not working for you, but I'm not an expert on how those fs2 apis are implemented and it's possible something changed.
Yes,
Yep, we've created #2610 with a proposal to try and solve that problem as well. |
Doesn't |
So, here is the code that "compiles" (in fs2 jargon) a
|
Thanks! @matil019 it seems |
@armanbilge Thanks for suggesting a workaround. Giving up the convenience of P.S. would you still like me to post the real usage of |
@matil019 it's a bit tricky, but if you want to use .compile(Compiler.target(Compiler.Target.forSync)) That way it will not use any Note that using the |
Nice to meet you!
I'm having a difficulty using Cats Effect 3 on Scala.js due to the change of the thread model.
Some JS functions such as
Event.preventDefault()
have to be run synchronously or won't have any effect. In CE2, we can just useIO
because it is run synchronously until a first async boundary. For example, if we wanted to implement someclick
event handler:In CE3, we must use
SyncIO
without converting it into anIO
. Unless I'm missing something, we have to resort toIO#unsafeRunAndForget
:The story is complicated because often
more
in the above example must be asynchronous. For example, it can be an AJAX call triggered by clicking a link. I guess this is going to be a common pattern in my project, and I definitely wouldn't like to sprinkleunsafeRunAndForget
all over it.If there were
IO#runAsync
like in CE2, the last code could be rewritten like this:(I'd like to point out
IO#runAsync
would be equivalent torunAff_
inpurescript-aff
, andIO#runAndForget
would correspond tolaunchAff_
.)The migration guide refers to
Dispatcher
as the replacement ofIO#runAsync
but it doesn't have any methods that returnSyncIO[_]
. I think it is reasonable becauseDispatcher
shouldn't be coupled toSyncIO
, but it may be helpful to haveIO
, as a concrete effect type, have a conversion fromIO
toSyncIO
.The text was updated successfully, but these errors were encountered: