Redux middleware handling multiple actions - javascript

I am using middleware in redux for some async logic execution.
My question is what happens when a action is being processed by the middleware and another action is dispatched before the completion of the first one, what will happen in this case, whether the action will be put to halt till the middleware complete processing or whether that action will pass the middleware which will start executing for this action as well (along with the first one).
I am a beginner to react and redux and don't know if the answer should be obvious as it is not to me.

TLDR: It cannot happen because JS is a sync language. It operates using event loop and tasks queue. Each async task (i.e. receiving fetch response or event listener triggered by user) is placed in a queue and is executed one by one. So when some task is executed another will wait in queue.
Also keep in mind that async function is more then one task. Each await indicates a new task.
There are a lot of explanation of this model in the internet by keywords: "JS event loop"
1, 2

Related

Will await calls be performed in parallel when looped over?

Suppose we have a look like this:
documents.forEach(url=>{
await fetch(url).
then(
document=>
console.log(document);
}
Will this load all the documents in parallel, or will the documents be loaded in serial?
In other words we could push the fetch promises into an array and then call Promise.all on that array which will execute all the promises in parallel.
IIUC there is no difference really except the Promise.all will fail on the first failure of a fetch request.
Provided the callback function is declared as async, then await can be used:
documents.forEach(async url => {
await fetch(url).then(console.log);
}
The sequence of execution is then as follows:
The forEach method is executed.
This includes calling the callback for each url, which happens one after the other
One execution of the callback will call fetch, which launches the HTTP request and returns immediately with a promise. In the background the non-JavaScript, lower-level API polls for the HTTP response to come in. Only that background part happens in parallel with the steps described here.
The then method is executed and the callback passed to it is registered. The then method immediately returns a promise
The await kicks in: the callback function's execution context is saved and it exits, returning a promise which this code ignores.
The next iteration takes place, repeating from step 3.
The forEach method ends. At this stage there are several non-JavaScript threads polling for HTTP responses, and there are several JS execution contexts pending for later execution.
In some unpredictable order (depending on the response time of the server giving the response), the fetch API resolves the promise that it had returned, and puts a message in the Promise Job Queue to indicate that.
The JavaScript event loop detects the event and proceeds with the execution of the callback registered in step 4 (the then callback), outputting to the console. The promise that was returned by the then method is resolved, which puts a new message in the Promise Job Queue.
The message is pulled from the queue and this will restore the corresponding execution context of the forEach callback. The execution continues after the await, and as there is nothing more to execute, the promise returned in step 5 is resolved (but no-one listens to that)
JavaScript monitors the event queue for more such work, and will at some point repeat at step 8.
No JavaScript code executes in parallel with JavaScript here, but the fetch API relies on non-JavaScript code, reaching "down" into Operating System functions, which do run in parallel with JavaScript code (and other OS functions).
Also note that the code is very similar to this non-async/await variant:
documents.forEach(url =>
fetch(url).then(console.log)
);
...because this callback also returns a promise. Except for the "saving execution context" part, which is not taking place here, the execution plan is quite similar.

javascript SetTimeout only invoked at function exit

I've noticed that setTimeout(function, milliseconds)
when used in middle of function will only be executed once function has ended regardless of timming given to it,
for example:
function doStuff(){
var begin = (new Date()).getTime();
console.log(begin);
setTimeout(function(){console.log("Timeout");},100);
doWork(4000);
var end = (new Date()).getTime();
console.log(end);
console.log("diff: "+(end-begin));
}
function doWork(num){
for(;num>0;--num) console.log("num");
}
doStuff();
the code above sets the timeout for 100 milliseconds but it is invoked only after all function completes which is much more then 100 milliseconds,
my question is:
why does this happen ?
how can i insure correct timing ?
JavaScript is not pre-emptive: it first finishes what it is doing before looking what is the next task that was posted in the queue (functions submitted for asynchronous execution). So even if a time-out expires, this will not influence the currently running code -- it does not get interrupted. Only when the stack of currently running functions have all returned and nothing remains to be run, JavaScript will check if there is a time-out request to be fulfilled, or whatever else is first in the queue.
From "Concurrency model and Event Loop" on MDN:
Queue
A JavaScript runtime contains a message queue, which is a list of messages to be processed. A function is associated with each message. When the stack is empty, a message is taken out of the queue and processed. The processing consists of calling the associated function (and thus creating an initial stack frame). The message processing ends when the stack becomes empty again.
Event loop
The event loop got its name because of how it's usually implemented, which usually resembles:
while(queue.waitForMessage()){
queue.processNextMessage();
}
queue.waitForMessage waits synchronously for a message to arrive if there is none currently.
"Run-to-completion"
Each message is processed completely before any other message is processed. This offers some nice properties when reasoning about your program, including the fact that whenever a function runs, it cannot be pre-empted and will run entirely before any other code runs (and can modify data the function manipulates). This differs from C, for instance, where if a function runs in a thread, it can be stopped at any point to run some other code in another thread.
A downside of this model is that if a message takes too long to complete, the web application is unable to process user interactions like click or scroll. The browser mitigates this with the "a script is taking too long to run" dialog. A good practice to follow is to make message processing short and if possible cut down one message into several messages.
To get code to run concurrently, you can make use of Web Workers. Web Workers run scripts in different threads.

Single thread Javascript and AJAX handling

Javascript is said to be single-threaded. Also AJAX is said to be asynchronous.
Consider a scenario;
I have a button and on click of it, I make a AJAX call which takes 5-6 seconds. Now the UI would not be blocked and the user does some other action (say click on another button which is now executing some code, while the AJAX response has been returned). Now in this case, since the other code is being executed, when would the AJAX callback be executed? Would it have to wait OR can it be executed in a parallel thread ?
The events are queued, so when the Ajax call completes, the handler for that would be queued to run on the event loop. When the single thread is done with your button handler, it'll then process the next event in the queue. So - you would have to wait for the code kicked off by the button click to finish, unless of course the Ajax request completed before the user clicked on the button, in which case the button click handler had to wait. The best you can do is split up your algorithm so that it runs in discrete chunks, these can be dropped onto the queue using setTimeout, but that is quite tricky.
So I have searched a little about this topic in general. Contrary to what I have imagined, javascript is nothing like multi-threaded. Instead, it has a queue of operations it performs.
The direct answer then is: Depending on the very exact timing, the AJAX callback might have to wait before click event completes. It also might have to wait for any other code that was executed at "the same moment".
This explains while things like while(true) or alert() stop every script on the site.

JavaScript callbacks and control flow

When are callbacks executed, for example the callback of a setTimeout() or a click event?
Do they pause code, that is already running, or do they wait until it has finished?
Example
I have a data structure (incrementalChanges) that records state changes caused by user interactions, for example mouse clicks. If I want to send all changes to another peer, I send him this data structure.
Another possibility is a full synchronisation (makeFullSync()), that means I send him my complete current state, so that I must empty the incremental changes (deleteIncrementalChanges()). That is, what you can see in the code. However I am not sure, what happens, if a user clicks something exactly between these two function calls. If this event fires immediately, then an item to the incrementalChanges structure would be added, but then in the second call directly deleted, so that it will never be sent and the other peer's state would became invalid.
makeFullSync();
/* what if between these 2 calls a new change is made, that is saved in the
changes data structure, that will be deleted by deleteIncrementalChanges()?
Then this change would be lost? If I change the order it is not better ...
*/
deleteIncrementalChanges();
Some good links and, in the case the first scenario (it pauses running code) is true, solutions are welcomed.
Javascript is single threaded, and keeps an event stack of stuff it needs to get to once it's done running the current code it's working on. It will not start the next event in the stack until the current one is finished.
If you make multiple asynchronous calls, such as calls for a server to update data on another client, you need to structure your code to handle the case where they don't necessarily reach the second client in the same order.
If you're sending changes one at a time to another user, you can time stamp the changes to track what order they were made on the first client.
Do they pause code, that is already running, or do they wait until it has finished?
They wait until it has finished. JavaScript is single threaded, more than one piece of code can not run at once. JS uses an event loop to handle asynchronous stuff. If an event such as a click handler or timer firing happens while another piece of code is running, that event is queued up and runs after the currently running code finishes executing.
Assuming makeFullSync(); and deleteIncrementalChanges(); are called in the same chunk of code they will be executed one after another without any click events being processed until after they have both run.
One almost exception to the nothing runs in parallel rule in JS is WebWorkers. You can send data off to a worker for processing which will happen in another thread. Even though they run in parallel their results are inserted back into the event loop like any other event.

Node.js: Connecting to a Server Using Sockets

I'm just starting to play with Node.js today, and thought I'd start with what I thought would be a simple script: Connecting to a server via sockets, and sending a bit of data, and receiving it back. I'm creating a command line utility. Nothing in the browser.
An example of a server would be memcached, beanstalkd, etc. It seems the net module is the right tool for the job, but I'm still a bit fuzzy on the Node.js way of doing things. Some help would be appreciated.
Update #1
Let me see if I can break this down in into a couple smaller questions. I hate even asking questions like this, but the Node.js documentation is very sparse, and most documentation written 6 months ago is already out dated.
1) So I can use net.stream.write() to send data to the remote server, but I don't know how to get a response back. I'm not even sure how to test when write() is finished, because it doesn't take a callback.
2) A few clues on how the whole event.emit thing works would be great. I think that's really the key stone I'm missing in those whole thing.
Update #2
Here's where I'm still confused on implementing a client program. Let me diagram a typical send request => get response system:
1) I bind callbacks to the net module to get responses and other events, including the necessary bindings to get a response from the server.
2) I use stream.write() to send a request to the server.
3) I then do nothing, because my bound "data" event will get the response from the server.
Here's where things get tricky. Suppose I call stream.write() twice before my bound "data" event is called. Now I have a problem. When the "data" event does happen, how do I know which of the 2 requests it's a response for? Am I guaranteed that responses will take place in the same order as requests? What if responses come back in a different order?
First of all, let's make clear what a EventEmitter is. JavaScript and therefore Node.js are asynchronous. That means, instead of having to wait for incoming connections on a server object, you add a listener to the object and pass it a callback function, which then, "as soon" as the event happens, gets executed.
There's still waiting here and there going on in the background but that has been abstracted away from you.
Let's take a look at this simple example:
// #1) create a new server object, and pass it a function as the callback
var server = net.createServer(function (stream) {
// #2) register a callback for the 'connect' event
stream.on('connect', function () {
stream.write('hello\r\n'); // as
});
// #3) register a callback for the 'data' event
stream.on('data', function (data) {
stream.write(data);
});
// #4) register a callback for the 'end' event
stream.on('end', function () {
stream.write('goodbye\r\n');
stream.end();
});
});
// #5) make the server listen on localhost:8124
server.listen(8124, 'localhost');
So we create the server and pass it the callback function, this function is not yet executed. Passing the function here is basically a shortcut for adding a listener for the connection event of the server object. After that we start the server at #5.
Now what happens in the case of an incoming connection?
Since the function we passed to createServer was bound to the connection event, it now gets executed.
It adds the connect, data and end event listeners to the stream object (which represents the individual connection) by hooking up callbacks for the events.
After that, the stream fires the connect event, therefore the function passed at #2 gets executed and writes hello\r\n to the stream. How does the function know which stream it should write to? Closures are the answer, the function inherits the scope it was created in, therefore inside the function stream is still referencing to the individual connection that triggered this very callback we're in right now.
Now the client sends some data over the connection, which makes the stream object call its data event, since we bound a function to this event at #3 we now echo the incoming data back to the client.
In case the client closes the connection, the function we've bound at #4 gets called, which writes goodbye\r\n and after that closes the connection from our side.
Does this make things a little bit more clear? Well it definitely makes the whole thing a lot easier. Node is, just as well as JavaScript is inside Browsers, single threaded. There's only one thing happening at a given point time.
To describe it simple, all these callbacks end up in a global queue and are then called one after another, so this queue may(abstracted) look like this:
| connection event for a new stream
| data event for stream #12
| callback set via setTimeout
v close event of yet another stream
These are now get executed top to bottom, nothing will ever happen in between those. There's no chance, that while you're doing something in the callback bound to the data event, something will other will happen and magically change the state of the system. Even if there is a new incoming connection on the server, its event will get queued up and it will have to wait until everything before it, including the data event you're currently in, finishes.

Categories

Resources