javascript in browser: asynchronous tasks executio

2019-07-09 04:05发布

I'm trying to wrap my head around and understand how javascript async works in single threaded browser environment.

As asynchronous we can treat both timers and xhr requests. Now suppose I have something like below

function doStuff() {
    for(var i=0; i<100000000; i++) {
        // do something to make proc busy
        if(i%1000 === 0) {
            console.log('in for loop');
        }
    }
}


setTimeout(function() {
    console.log('timed out')
}, 2);
doStuff();
doStuff();
doStuff();

Timer is set to really small value (2ms), so I suppose it should work as follows:

1) timer callback is queued

2) doStuff() is executed (as a whole?), it takes some time (more than those 2 ms)

3) timer callback is run as there is a moment betweet one doStuff() execution and another

4) next doStuff() is called

4) last doStuff() is called

What I see instead is that all three doStuff() things are done before timer callback fires. And it is much longer time than those 2ms. Yes, I know this time value set in setTimeout is not guaranteed.

My question is how does javascript executes code? What is the smallest, atomic block that will be executed at once before something from async queue gets invoked?

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-07-09 04:33

WebWorker is updated solution for Async Javascript. For sencha developers here is the tutorial and still don't depend on setTimeout

查看更多
我想做一个坏孩纸
3楼-- · 2019-07-09 04:35

You're wrong here:

3) timer callback is run as there is a moment betweet one doStuff() execution and another

The why is in the answer to the following question:

What is the smallest, atomic block that will be executed at once before something from async queue gets invoked?

JavaScript uses something called an event loop. Each event loop cycle can be called a "tick". On every tick, the interpreter checks if there are asynchronous callbacks to be executed (e.g., a setTimeout callback where the timeout has already expired).

All other, synchronous, operations take place within the same tick. So, on your example, the timer will be checked for expiration in the next tick, but all three calls to doStuff are executed in the current tick. That's why the time value passed to setTimeout is not guaranteed: there's no way to know how long it will take until the next tick, so we usually say the callbacks will run "as soon as possible". In the case of setInterval, some calls may even be dropped; for example, when the next tick takes place after twice the defined interval, the callback only runs once.

查看更多
做个烂人
4楼-- · 2019-07-09 04:47

Since Javascript is single threaded, timeouts can only processed when the interpreter becomes idle. By the time you queue the timeout function, the interpreter is still processing your main script, and won't be able to process the timeout until it finishes.

setTimeout or setInterval or any other async event will only be handled when no code is running. They will not interrupt the current code. Any piece of running javascript code that blocks will delay the execution of all event handlers.

查看更多
登录 后发表回答