Closed crocket closed 7 years ago
Does ThrowWouldBlock
make sense in any case?
What would it return to JavaScript if it did not throw an exception?
Is it impossible to return anything from an asynchronous callback?
In the case of syncCallback
the caller will be expecting a value (otherwise they could have just used asyncCallback
). So we will need to consider what value we return when the callback has not yet finished. One option might be to pass "on blocking result" JSVal
to syncCallback
(then the user can choose).
Is it impossible to return anything from an asynchronous callback?
Yes.
Yes.
It seems syncCallback'
and its siblings are not useful because they cannot be used with side effects. Side effects can block a thread. I think I can document this issue on README.
In the case of syncCallback the caller will be expecting a value
syncCallback :: OnBlocked -> IO () -> IO (Callback (IO ()))
doesn't seem to return a value to javascript.
One option might be to pass "on blocking result" JSVal to syncCallback (then the user can choose).
What do you mean?
Sorry wrote those responses in a rush.
It seems syncCallback' and its siblings are not useful because it cannot be used with side effects. Side effects can block a thread. I think I can document this issue on README.
I think you realise, but not all functions with side effects can block a thread. putStrLn can because it simulates the buffering and tries to avoid blocking all the other things that JavaScript might be doing.
Having said that syncCallback'
should be avoided and syncCallback
is probably the best option in most cases and it would be good to reflect that in the documentation.
In the case of syncCallback the caller will be expecting a value
syncCallback :: OnBlocked -> IO () -> IO (Callback (IO ())) doesn't seem to return a value to javascript.
Sorry I meant to say:
In the case of syncCallback' the caller will be expecting a value (otherwise they could have just used syncCallback).
One option might be to pass "on blocking result" JSVal to syncCallback (then the user can choose).
What do you mean?
Again I was thinking of syncCallback'
but got the names mixed up.
When the JavaScript callback is called it has to return something (even if it returns undefined
). Currently I think syncCallback
returns undefined then it is asked to ContinueAsync
. This is unsurprising to the caller because they were never expecting to get anything back anyway.
syncCallback'
would also have to return something if it was going to ContinueAsync
. However in this case the caller will be expecting something to be returned. Instead of returning undefined
it might be nicer to let the creator of the callback specify what the return value should be if the callback it going to ContinueAsync
.
The function might be something like
syncCallbackContinueAync :: JSVal -> IO JSVal -> IO (Callback (IO JSVal))
That extra JSVal argument would be the default value returned to the JavaScript caller when the callback it going to be continued asynchronously. The real return value would have to be discarded in that situation (because it would be computed too late to be returned).
I think we really need some example use cases though so that we can figure out what (if anything) will be useful.
I have never used syncCallback'
and ghcjs-dom
does not create wrappers for it (it creates type safe wrappers for syncCallback ThrowWouldBlock
, syncCallback ContinueAsync
and asyncCallback
).
If syncCallback'
and its derivatives weren't used, then we wouldn't have to solve this problem. Thus, I close this issue. When it becomes an actual problem, an issue will be opened.
If a callback function passed to
syncCallback'
executesputStrLn
multiple times, the callback throws an exception.This is not desirable. It should continue asynchronously by default, or it should accept
OnBlocked
.