Javascript引擎如何在浏览器中执行Javascript?
问题不是为了解决问题,而是为了更好地理解系统的问题 专家们!我知道,无论何时将javascript代码输入javascript引擎,它都会立即由javascript引擎执行。因为,我还没有看到引擎的源代码,所以我有以下几个问题:Javascript引擎如何在浏览器中执行Javascript?,javascript,javascript-engine,Javascript,Javascript Engine,问题不是为了解决问题,而是为了更好地理解系统的问题 专家们!我知道,无论何时将javascript代码输入javascript引擎,它都会立即由javascript引擎执行。因为,我还没有看到引擎的源代码,所以我有以下几个问题: <script type="text/javascript" src="FILE_1.js" ></script> <script type="text/javascript" src="FILE_2.js" ></script
<script type="text/javascript" src="FILE_1.js" ></script>
<script type="text/javascript" src="FILE_2.js" ></script>
假设我正在从远程服务器加载两个文件,即FILE_1.js和FILE_2.js。
文件_2.js中的代码需要文件_1.js中的一些代码。所以我包括了如下文件:
<script type="text/javascript" src="FILE_1.js" ></script>
<script type="text/javascript" src="FILE_2.js" ></script>
所以,我希望我已经完成了Javascript引擎所需要的工作。不幸的是,我在文件_1.js中编写了5000KB的代码,而在文件_2.js中有5KB的代码。由于服务器是多线程的,所以文件_2.js肯定会在文件_1.js完成之前加载到我的浏览器中
javascript引擎如何处理这个问题
如果将代码从文件_2.js移动到内联脚本标记,如下所示,javascript引擎将采取哪些操作来管理此依赖关系
<script type="text/javascript" src="FILE_1.js" ></script>
<script type="text/javascript" >
// Dependent code goes here
</script>
//依赖代码在这里
注:我不期望单字答案单线程。我只想知道到底是谁在管理发出请求的浏览器、javascript引擎还是普通人?如果请求/响应由common guy处理,那么javascript引擎如何意识到这一点?当我发布关于代码行为的答案时,我总是喜欢去两个地方:
defer
或async
属性之前检查此规则的例外列表。这一点在本文中有很好的说明
想象一下,这是有道理的:
//FILE_1.js
var trololo = "Unicorn";
....
// 1 million lines later
trololo = "unicorn";
var message = "Hello World";
//FILE_2.js
alert(message); // if file 1 doesn't execute first, this throws a reference error.
通常最好使用模块加载器(它将延迟脚本插入和执行,并为您正确管理依赖关系)
目前,最好的方法是使用类似或的东西。将来,我们将能够使用ECMAScript 6模块
实施:
你提到了,我忍不住。因此,如果我们检查源代码(在WebKit中仍然类似):
很好,所以我们可以在源代码中看到它按解析顺序添加了它们——就像规范所说的那样
让我们看看a:
void ScriptRunner::queueScriptForExecution(ScriptLoader*ScriptLoader,
资源PTR资源,
ExecutionType(执行类型){
.....
//按执行顺序添加,如我们所见,这只是
//将其添加到队列中
订单执行中的案例:
m_scriptstoexecuteinnorder.append(PendingScript(元素,resource.get());
打破
}
并且,它使用计时器,在准备就绪时(或者如果没有任何待处理内容,则立即)逐个激发它们:
void ScriptRunner::timerFired(Timer*Timer)
{
...
scripts.swap(m_scriptstoexecuteson);
对于(大小i=0;iexecute(resource);
m_document->decrementLoadEventDelayCount();
}
服务器将等待文件1完全加载,然后再执行文件2,因为文件2可能依赖于它。如果它们是独立的,您可以始终使用模块加载器,或者在脚本中添加defer
属性。@BenjaminGruenbaum是正确的,只要您按该顺序加载它们。也就是说,我希望5000KB是一个虚构的数字;tha对于客户端脚本来说,这是一个巨大的挑战!既然ECMAScript 6已经发布了,你能更新一下这个答案吗?这有什么关系?这是一个不同于DOM API的规范,因为你指出最好使用模块加载器,你说可以使用ES6来实现它,我想知道更多this@Mark此时ECMAScript 6模块尚未准备好生产瞬间(可悲)-它们可以工作,但大多数时候人们仍然使用webpack(这是理所当然的)@BenjaminGruenbaum为什么es6模块还没有投入生产?除了IE,所有主要浏览器都支持它。如果你不关心IE,我会说使用es6模块是安全的。
void ScriptRunner::queueScriptForExecution(ScriptLoader* scriptLoader,
ResourcePtr<ScriptResource> resource,
ExecutionType executionType){
.....
// Adds it in the order of execution, as we can see, this just
// adds it to a queue
case IN_ORDER_EXECUTION:
m_scriptsToExecuteInOrder.append(PendingScript(element, resource.get()));
break;
}
void ScriptRunner::timerFired(Timer<ScriptRunner>* timer)
{
...
scripts.swap(m_scriptsToExecuteSoon);
for (size_t i = 0; i < size; ++i) {
....
//fire!
toScriptLoaderIfPossible(element.get())->execute(resource);
m_document->decrementLoadEventDelayCount();
}