From CoffeeScript Accelerated JavaScript Development, chapter 6.6, question:
count = 10
h = setInterval (-> count--),100
do (->) until count is 0
clearInterval h
console.log 'Suprise!'
count won't be 0,I try to change 100 to 0,result is the same.
which stack is the setInterval in? when will the callback function (-> count--) run?
Javascript is strictly single-threaded.
All asynchronous callbacks will only run after your code finishes running.
Your infinite loop never finishes running, so the setInterval callback never runs.
Related
I have a function that looks like this:
public Flowable<Integer> max(int a, int b){
// *** Part 1 - start ***
int max = Math.max(a,b);
// *** Part 1 - end ***
return Flowable.defer(() -> {
// *** Part 2 start ***
return Flowable.just(max);
// *** Part 2 end ***
});
}
When I now subscribe like this:
EDITED:
max(3,4).subscribeOn(Schedulers.io()).subscribe();
Will the code from Part 1 run on Schedulers.io()?
What are problems that can happen when you write a function like this?
What code runs in which thread?
What is the difference for part 1 if its not in the stream? Or is it in the stream?
When I now subscribe like this:
That code doesn't subscribe, you have to call subscribe().
Will the code from Part 1 run on Schedulers.io()?
The code in max() runs as soon as it is invoked on some thread: it calculates the max and creates a Flowable capturing the bigger value.
What are problems that can happen when you write a function like this?
Part 1 executes on the caller thread which may not be what you wanted. At that point, RxJava isn't even involved.
What code runs in which thread?
max() runs on the caller thread and nothing else gets executed.
What is the difference for part 1 if its not in the stream? Or is it in the stream?
Part 1 is out of the stream. You have to put those computation into the stream via fromCallable for example, although such trivial operations may not be worth putting into a stream.
public Flowable<Integer> max(int a, int b){
return Flowable.fromCallable(() ->
// *** Part 1 - start ***
Math.max(a, b)
// *** Part 1 - end ***
);
}
max(3, 4)
.subscribeOn(Schedulers.io())
.subscribe(v -> {
System.out.println(Thread.currentThread());
System.out.println(v);
});
Will the code from Part 1 run on Schedulers.io()?
Ans: Part one will run on main thread or caller thread. As you didn't put it under the rxjava method.
What code runs in which thread?
Ans: part 2 runs on caller thread. It may be main thread or a new worker thread.
What is the difference for part 1 if its not in the stream? Or is it in the stream?
Ans: It is out of the stream. You may get output from it. But that didn't depend on rxjava.
Use All code inside the rxjava method. Otherwise stream flow may differ. This type of simple calculation can be used on main thread. use rxjava when working with database or rest api call.
It should be simple, but I have no idea how to do it. I want to run ScalaZ Task in the current thread. I was surprised task.run doesn't run on the current thread, as it is synchronous.
Is it possible to run it on the current thread, and how to do it?
There were some updates and deprecations since http://timperrett.com/2014/07/20/scalaz-task-the-missing-documentation/.
Right now the recommended way of calling task synchronously is:
task.unsafePerformSync // returns result or throws exception
task.unsafePerformSyncAttempt // returns -\/(error) or \/-(result)
Keep in mind, though, that it is not exactly done in the caller's thread - the execution is perfomed in a thread pool defined for a task, but the caller's thread blocks until the execution is finished. There is no way of making the task run exactly in the same thread.
In general, if Task.async is used - there is no way to make composite Task always stay in the same thread as cb (callback) can be called from any place (any thread), so that in a chain like:
Task
.delay("aaa")
.map(_ + "bbb")
.flatMap(x => Task.async(cb => completeCallBackSomewhereElse(cb, x)))
.map(_ + "ccc")
.unsafePerformSync
_ + "bbb" is gonna be executed in a caller's thread
_ + "ccc" is gonna be executed in Somewhereelse's thread as scalaz have no control over it.
Basically, this allows a Task to be a powerful instrument for asynchronous operations, so it might not even know about underlying thread pools or even implement behavior without pure threads and wait/notify.
However, there are special cases where it might work as caller-runs:
1) No Strategy/Task.async related stuff:
Task.delay("aaa").map(_ + "bbb").unsafePerformSync
unsafePerformSync uses CountDownLatch to await for result of runAsync, so if there is no async/non-deterministic operations on the way - runAsync will use caller's thread:
/**
* Run this `Future`, passing the result to the given callback once available.
* Any pure, non-asynchronous computation at the head of this `Future` will
* be forced in the calling thread. At the first `Async` encountered, control
* switches to whatever thread backs the `Async` and this function returns.
*/
def runAsync(cb: A => Unit): Unit =
listen(a => Trampoline.done(cb(a)))
2) You have control over execution strategies. So this simple Java trick will help. Besides, it's already implemented in scalaz and called Strategy.sequential
P.S.
1) If you simply want to start a computation as soon as possible use task.now/Task.unsafeStart.
2) If you want something less heavily related on asynchronous stuff but still lazy and stack-safe, you might take a look here (it's for Cats library) http://eed3si9n.com/herding-cats/Eval.html
3) If you just need to encapsulate side-effects - take a look at scalaz.effect
I was looking over some Scala server code and I saw thins async/await block:
async {
while (cancellationToken.nonCancelled) {
val (request, exchange) = await(listener.nextRequest)
respond(exchange, cancellationToken, handler(request))
}
}
How can this be correct syntax?
As I understand it:
For every execution of the while loop
Thread 1 will execute the code from the while loop except the one in the await clause.
Thread 2 will go in the await clause.
But then Thread 1 will have val (request, exchange) uninstantiated in case Thread 2 doesn't finish computing.
These values will be passed to the respond and handler methods uninstantiated.
So how can you have an assignment in two different threads?
So how can you have an assignment in two different threads?
async-await's main goal is to allow you to do asynchronous programming in a synchronous fashion.
What really happens is that the awaited call executes listener.nextRequest and asynchronously waits for it's completion, it doesn't execute the next line of code until then. This guarantees that if the next line of code is executed, it's values are populated. The assignment should happen where it is visible to the next LOC in the method.
This is possible due to the fact that the async macro actually transforms this code into a state-machine, where the first part is the execution up until the first await, and the next part is everything after.
( I've read a lot about async and I wonder what happens if there is a mix of async function call and non-async) and im talking about THREAD pov .
( I know that mix should not be done , but im asking in order to understand the flow better)
suppose I have(cube 1) function which calls async functions which calls asyc function.
(please notice that cube 1 function is not async)
Question : when the control reaches (cube 3) await Task.Delay(100); --
what is really happening as the control reaches cube3 await ? does the control is back(and blocked) at the pink arrow (cube 1 ) or does the control is released and still awaits ( orange arrow)
When control reaches the await statement in Cube3, Task.Delay() is called and immediately returns a Task that will complete after the delay. The rest of CalculateAnswer() is refactored into a continuation that will run when the Task returned by Delay() completes, and CalculateAnswer() immediately returns a Task<int> that will complete when that continuation completes.
CallCalculateAnswer() awaits the Task<int> returned by CalculateAnswer(), so the same logic applies: the code running after the await (i.e. the return statement) is refactored into a continuation that will run when the Task<int> completes, and CallCalculateAnswer() proceeds to return its own Task<int>.
StartChain(), however, does not await the Task<int> produced by CallCalculateAnswer(), so no continuation is generated. Instead, it stores the task into a local variable and returns. Therefore, the orange arrow in your question is the right one.
Note that, in this specific case, since nothing is done with the Task<int> returned by CallCalculateAnswer() and it is only stored in a local variable, it becomes "forgotten" once StartChain() returns: the task will complete (or fail) some time in the future, but its result (the int it produces) will be lost.
Update following comments: The pink arrow in your question implies you're expecting StartChain() to block, waiting for the task returned by CallCalculateAnswer() to complete, because it is not async and does not await that task. This is not what happens, as the usual control flow semantics apply: the method has returned a task, so you get a reference to that task and nothing more.
If you want StartChain() to block, you can use Task.Wait(), Task<T>.Result, or similar on the task returned by CallCalculateAnswer().
This is a question about Scala continuations. Can resets be nested? If they can: what are nested resets useful for ? Is there any example of nested resets?
Yes, resets can be nested, and, yes, it can be useful. As an example, I recently prototyped an API for the scalagwt project that would allow GWT developers to write asynchronous RPCs (remote procedure calls) in a direct style (as opposed to the callback-passing style that is used in GWT for Java). For example:
field1 = "starting up..." // 1
field2 = "starting up..." // 2
async { // (reset)
val x = service.someAsyncMethod() // 3 (shift)
field1 = x // 5
async { // (reset)
val y = service.anotherAsyncMethod() // 6 (shift)
field2 = y // 8
}
field2 = "waiting..." // 7
}
field1 = "waiting..." // 4
The comments indicate the order of execution. Here, the async method performs a reset, and each service call performs a shift (you can see the implementation on my github fork, specifically Async.scala).
Note how the nested async changes the control flow. Without it, the line field2 = "waiting" would not be executed until after successful completion of the second RPC.
When an RPC is made, the implementation captures the continuation up to the inner-most async boundary, and suspends it for execution upon successful completion of the RPC. Thus, the nested async block allows control to flow immediately to the line after it as soon as the second RPC is made. Without that nested block, on the other hand, the continuation would extend all the way to the end of the outer async block, in which case all the code within the outer async would block on each and every RPC.
reset forms an abstraction so that code outside is not affected by the fact that the code inside is implemented with continuation magic. So if you're writing code with reset and shift, it can call other code which may or may not be implemented with reset and shift as well. In this sense they can be nested.