Javascript singlethread - Doubt

Asked

Viewed 86 times

3

I’m having a strange doubt, I’d like your help to try to clarify..

Since Javascript is singlethread and asynchronous calls try to bypass this "weakness", what happens when a Webkit process crashes ?

Think of that code:

function preloadImage(url)
{
    var img=new Image();
    img.src=url;
}

If we implement onload it will only be called when Webkit finishes processing the image. If Webkit has some while(true) (it’s just an example) in the process of reading the image and loading it into memory, the javascript code would get stuck, causing all the asynchronous calls to jam as well?

  • Timeout and Interval are not asynchronous

  • I thought they were, anyway, I edited the question.

  • The question is very vague, Voce has some code to show what you’re trying to ask?

  • I did not understand your question, your example code does not agree with what you wrote, may be more specific please?

  • This example code is just to exemplify a function that has something asynchronous, as I said just below about implementing onload. What I want to know is if this is the process of reading the image (process in which the Webkit load the image in a memory buffer (I believe it is so)) traverse, what will happen with the asynchronous calls that have not yet returned. They will continue running if they don’t have dependency with this Webkit process ?

  • Depends on the browser this, Chrome for example, a simple error it hangs the execution of all the rest of the code.. but there are errors that does not lock. It depends a lot on the situation, the error of the code and the browser. It is necessary to debug and see what happens to be sure.

  • Related: http://answall.com/questions/100654/comorapportfrozen thread-locked

Show 2 more comments

1 answer

6


Your doubt involves a little understanding of how Javascript works.

You’re right when you say language is single threaded (at least in the implementation of browsers).

As to the asynchronous calls that you mention, I ask you to follow me in a well summarized explanation of what happens behind the scenes in a Javascript code execution. Once you understand this part, your question will be easily answered.

Come on.

What happens is that the language in the browser runs within a running context (Runtime): each page/tab/iframe has its own isolated environment. And this execution context involves three aspects: pile (stack), message queue (Queue) and memory (heap).

inserir a descrição da imagem aqui

In a very simplistic way, we can say that the pile is exactly what is being processed, while the message queue is what is waiting to be processed.

The most common example of a message going to the message queue is the occurrence of a event that was being monitored. For example, when we executed a botao.addEventListener('click', function() { });, the browser understands this instruction as: "every time someone clicks on this button, I’ll put this function you passed me in the message queue."

Another common use for the message queue is the return of a call XHR . Or even, the function passed as argument of setTimeout, or setInterval (although the reported time is zero, as we will see later).

What I’m getting at is that one of the principles of this flow is that the next message is not placed on the execution stack as long as the stack is not empty. That is, in other words, all running functions (one function that called the other that called the other, for example) should end for the next message to be placed on this stack. Message only leaves the message queue when stack is completely empty.

Thus, although the callback could theoretically be executed immediately, the function has to end so that it can be processed. Consider the code below:

console.log("início");

setTimeout(function() {
    console.log("dentro do setTimeout()")
}, 0);

console.log("fim");

Upshot:

//início
//fim
//dentro do setTimeout()

Although the setTimeout be in time zero, he NEVER will be executed before the function ends, because it went to the queue. Once the stack is finished, the next message will be called (note that if the queue is full of messages, it may take a while well over zero for the start execution. Hence the specification of the setTimeout says that the time entered in the parameter is the minimum, and not the guaranteed time: because the queue can be with messages in front.).

All this conceptualization I believe serves to answer your question. Well, regardless of where the code comes from (be it a setTimeout, or a callback of an XHR call etc.), when it runs to the stack, and this function never closes (an infinite loop, for example), the Runtime hangs. That function will never close, the stack will not clear, and the next message will never be invoked.

For example, please note this code:

setTimeout(function() {
    while (true) {};
}, 3000);
console.log("olá!");

What happens when this code is executed:

  1. When calling the function setTimeout, the browser was instructed to, as soon as 3 seconds passed, place that anonymous function at the end of the message queue.
  2. Right after, he prints a "hello!".
  3. Function closed and battery cleaned.
  4. The event loop is checking for new messages. For now, nothing.
  5. As soon as 3 seconds has passed, the browser has placed that anonymous function in the message queue.
  6. Loop saw that it had new message and removed it from the queue and put it in the stack to be executed.
  7. The while (true) {}; caused an infinite loop and locked the function. It will never return, the browser latch and no more events run.

That said, going deeper into your doubt if there is any problem in implementing the browser for its internal functions (for example, the code makes an XHR request and the browser gets lost and never puts the callback in the queue - either error or success -, or tries to load an image and an untreated error occurs in this upload), all this is considered BUG browser and has nothing to do with Javascript execution flow, as the native code is usually C++ (Google’s V8, at least). The results for the user vary according to the nature and dimension of the error: the script flow can be stopped if there is one crash, the browser can return an unexpected result, a callback never be invoked etc.

  • Excellent reply, thank you! Just to conclude based on thinking my example, when we wait for an image onload, it goes to the queue, right? And she stays there until she’s processed, right? So if the process of loading the image in memory of the browser See some bug, an infinite loop and never return to callback, the same will not interfere in any way in the functioning of the JS code, that’s it?

  • 1

    @Paulogustavo of nothing. In fact, when you arrow a onload it tells the browser that, only as the image loads, it will place the callback message in the queue. Until then, in this limbo (between onload and callback go to JS execution queue), this processing is native code of the browser and if there is a bug, it will depend on the error. If it is a general crash, it has nothing to do, it locks everything down. If it is another mistake, it can happen that callback never gets in line and the onload never to be invoked.

  • 1

    @Paulogustavo This theoretically, why in practice browsers are too mature to handle these errors, and when he can’t load an image for example, for which reason, he just sends an error callback (in his example, a onerror).

  • Man, thank you so much. These doubts have arisen because we even have an implementation with several modifications in qtwebkit. And because of that, a need arose to have to optimize the process as the canvas and images work, and by some modifications already made by the team, the javascript code began to behave strangely in asynchronous calls. Your reply will be very helpful to continue. Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.