Дисклеймер:
С веб-воркерами (и чем-то подобным) все и так понятно, поэтому далее я пишу вне их использования
Ответ на ваш вопрос сильно зависит от понимания заголовка. Если мы говорим про браузер или какую-то его часть - то вполне вероятно это действительно работа в отдельном потоке. Только это работа
браузера, а не javascript. Вот например статья про node.js
https://codeburst.io/how-node-js-single-thread-mec... (достаточно прочитать Top Highlight)
The main event loop is single-threaded but most of the I/O works run on separate threads, because the I/O APIs in Node.js are asynchronous/non-blocking by design, in order to accommodate the event loop.
Таким образом про node.js можно сказать, что оно - многопоточное приложение. Но вот с точки зрения javascript-а, то есть как-бы изнутри него - node.js - однопоточный. Иными словами: весь JavaScript код и в браузере и в ноде позиционирует себя как однопоточное приложение. И исполняется так же. Но какие-то операции вне языка (I/O или тот же xhr) могут быть реализованы как угодно браузером. Это строго говоря вопрос больше про устройство среды исполнения.
Я подвис, но мой ответ был, что JS можно считать многопоточным и я так предполагаю из-за наличия xmlhttprequest запросов (в простонародии ajax).
- строго говоря это не так. Хотя мне кажется это не далеко от истины. Если мы поговорим, что язык многопоточный, я думаю мы имеем ввиду, что языком поддерживается работа с потоками, а не то как он устроен изнутри или как изнутри устроена среда его исполнения. Потому как какая-нибудь сборка мусора может выполняться в отдельном потоке, но это не делает сам ЯЗЫК много поточным.
Вопрос: Относится ли WebAPI к движку JavaScript и корректно ли утверждать, что фактически xmlhttprequest выполняется в отдельном потоке от остального кода JavaScript?
- Нет. Это API которое браузер предоставляет внутрь движка. Это можно проследить взяв например node.js и сравнив с браузерным js. Так, например, в node.js доступны внутренние модули (fs, http, path etc.)., а также другие фичи, такие как process.argv и так далее, в то время как в браузере есть WebAPI, например, fetch. При этом в браузере нет require('path'), зато в ноде нет fetch.
И это при том что и браузер (chrome) и node.js работают на одном движке (V8).
В node.js нет доступа к xhr, что уже может навести на мысли о том, что это не часть движка.
Важное замечание: я думаю сравнивая node.js и браузер, можно сформировать какое-то представление о том, что из себя представляет чистый движок js, но тем не менее это не полностью достоверно. Потому как, например, и там и там есть совместимые друг с другом setInterval и setTimeout, однако (если мне не изменяет память) они не входят в движок.
Если хочется четче понять где проходит граница, но не так сильно чтобы читать спеки - можно попробовать встроить движок самостоятельно. V8 или SpiderMonkey (в Firefox'е) умеют встраиваться в другие приложения и если встраивать их самостоятельно - и API внутрь движка (причем конкретной его реализации, а не абстрактного понятия) нужно будет прокидывать самостоятельно - тогда можно будет увидеть, что в голом движке не будет ни setTimeout, ни alert, ни console.log, ни document ни даже require и т.д.