Is JavaScript guaranteed to be single-threaded?

2018-12-31 01:06发布

JavaScript is known to be single-threaded in all modern browser implementations, but is that specified in any standard or is it just by tradition? Is it totally safe to assume that JavaScript is always single-threaded?

12条回答
君临天下
2楼-- · 2018-12-31 01:28

JavaScript/ECMAScript is designed to live within a host environment. That is, JavaScript doesn't actually do anything unless the host environment decides to parse and execute a given script, and provide environment objects that let JavaScript actually be useful (such as the DOM in browsers).

I think a given function or script block will execute line-by-line and that is guaranteed for JavaScript. However, perhaps a host environment could execute multiple scripts at the same time. Or, a host environment could always provide an object that provides multi-threading. setTimeout and setInterval are examples, or at least pseudo-examples, of a host environment providing a way to do some concurrency (even if it's not exactly concurrency).

查看更多
深知你不懂我心
3楼-- · 2018-12-31 01:28

I would say that the specification does not prevent someone from creating an engine that runs javascript on multiple threads, requiring the code to perform synchronization for accessing shared object state.

I think the single-threaded non-blocking paradigm came out of the need to run javascript in browsers where ui should never block.

Nodejs has followed the browsers' approach.

Rhino engine however, supports running js code in different threads. The executions cannot share context, but they can share scope. For this specific case the documentation states:

..."Rhino guarantees that accesses to properties of JavaScript objects are atomic across threads, but doesn't make any more guarantees for scripts executing in the same scope at the same time.If two scripts use the same scope simultaneously, the scripts are responsible for coordinating any accesses to shared variables."

From reading Rhino documentation I conclude that that it can be possible for someone to write a javascript api that also spawns new javascript threads, but the api would be rhino-specific (e.g. node can only spawn a new process).

I imagine that even for an engine that supports multiple threads in javascript there should be compatibility with scripts that do not consider multi-threading or blocking.

Concearning browsers and nodejs the way I see it is:

  • Is all js code executed in a single thread? : Yes.

  • Can js code cause other threads to run? : Yes.

  • Can these threads mutate js execution context?: No. But they can (directly/indirectly(?)) append to the event queue.

So, in case of browsers and nodejs (and probably a lot of other engines) javascript is not multithreaded but the engines themselves are.

查看更多
千与千寻千般痛.
4楼-- · 2018-12-31 01:28

Well, Chrome is multiprocess, and I think every process deals with its own Javascript code, but as far as the code knows, it is "single-threaded".

There is no support whatsoever in Javascript for multi-threading, at least not explicitly, so it does not make a difference.

查看更多
若你有天会懂
5楼-- · 2018-12-31 01:33

Yes, although Internet Explorer 9 will compile your Javascript on a separate thread in preparation for execution on the main thread. This doesn't change anything for you as a programmer, though.

查看更多
步步皆殇っ
6楼-- · 2018-12-31 01:34

Actually, a parent window can communicate with child or sibling windows or frames that have their own execution threads running.

查看更多
呛了眼睛熬了心
7楼-- · 2018-12-31 01:34

I've tried @bobince's example with a slight modifications:

<html>
<head>
    <title>Test</title>
</head>
<body>
    <textarea id="log" rows="20" cols="40"></textarea>
    <br />
    <button id="act">Run</button>
    <script type="text/javascript">
        let l= document.getElementById('log');
        let b = document.getElementById('act');
        let s = 0;

        b.addEventListener('click', function() {
            l.value += 'click begin\n';

            s = 10;
            let s2 = s;

            alert('alert!');

            s = s + s2;

            l.value += 'click end\n';
            l.value += `result = ${s}, should be ${s2 + s2}\n`;
            l.value += '----------\n';
        });

        window.addEventListener('resize', function() {
            if (s === 10) {
                s = 5;
            }

            l.value+= 'resize\n';
        });
    </script>
</body>
</html>

So, when you press Run, close alert popup and do a "single thread", you should see something like this:

click begin
click end
result = 20, should be 20

But if you try to run this in Opera or Firefox stable on Windows and minimize/maximize window with alert popup on screen, then there will be something like this:

click begin
resize
click end
result = 15, should be 20

I don't want to say, that this is "multithreading", but some piece of code had executed in a wrong time with me not expecting this, and now I have a corrupted state. And better to know about this behavior.

查看更多
登录 后发表回答