gpt4 book ai didi

javascript - 尝试理解 Javascript 脚本的执行顺序。尝试过异步、延迟、动态加载脚本,但都有不可预测的结果

转载 作者:行者123 更新时间:2023-12-02 20:55:12 25 4
gpt4 key购买 nike

我有以下代码,根据代码我假设操作顺序为:

  1. 脚本 one.js 将被下载并执行,这将更新 dom,并立即更新 div1 并显示在浏览器中。
  2. sleep 函数会在 sleep 命令下暂停运行 8 秒
  3. 脚本two.js将被下载并执行,dom更新并显示在浏览器中
  4. 脚本 Three.js 将被下载并执行,dom 被更新并显示在浏览器中

然而事实并非如此。在 sleep 命令完成之前,浏览器中不会显示/更新任何内容。在控制台中,“SLEEP start”在“ONE start”之前被记录。

我尝试在调用 loadScript 时启用异步,我已将 sleep 命令移至two.js 内。没有什么变化。我在这里缺少什么?我将如何更改我的代码以实现正确的下载和执行?

这是我的代码:

html:

<!doctype html>
<html lang="en">
<body>

<div id="div1" style="background-color: orange;">
</div>

<script>
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
//console.log('sleep is executing');
} while (currentDate - date < milliseconds);
}

function loadScript(src, async_enabled = async_enabled) {
let script = document.createElement('script');
script.src = src;
script.async = async_enabled;
document.body.append(script);
}

loadScript("one.js", async_enabled = false);
console.log('SLEEP start');
sleep(8000);
console.log('SLEEP stop');
loadScript("two.js", async_enabled = false);
loadScript("three.js", async_enabled = false);
</script>

</body>
</html>

one.js:

    console.log('ONE start');
let one = document.getElementById('div1');
let p1 = document.createElement('p');
p1.innerHTML = 'One';
one.appendChild(p1);
console.log('ONE stop');

两个.js:

    console.log('TWO start');
let two = document.getElementById('div1');
let p2 = document.createElement('p');
p2.innerHTML = 'Two';
two.appendChild(p2);
console.log('TWO stop');

三.js:

    console.log('THREE start');
let three = document.getElementById('div1');
let p3 = document.createElement('p');
p3.innerHTML = 'Three';
three.appendChild(p3);
console.log('THREE stop');

更新我只是使用 sleep 命令来帮助我理解 js 脚本是如何加载和执行的(顺序)。我真的不想在我的代码中使用 sleep 命令。我将我的 html 更改为:

<!doctype html>
<html lang="en">
<body>

<div id="div1" style="background-color: orange;">
</div>

<script>
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
//console.log('sleep is executing');
} while (currentDate - date < milliseconds);
}

function loadScript(src, async_enabled = async_enabled) {
let script = document.createElement('script');
script.src = src;
script.async = async_enabled;
document.body.append(script);
}

loadScript("one.js", async_enabled = false);
</script>
</body>
</html>

将 one.js 更改为:

    console.log('ONE start');
let one = document.getElementById('div1');
let p1 = document.createElement('p');
p1.innerHTML = 'One';
one.appendChild(p1);
console.log('ONE stop');
loadScript("two.js", async_enabled = false);

并将 Two.js 更改为:

    console.log('TWO start');
sleep(5000);
let two = document.getElementById('div1');
let p2 = document.createElement('p');
p2.innerHTML = 'Two';
two.appendChild(p2);
console.log('TWO stop');

我仍然得到相同的结果。我知道我应该理解为什么会发生这种情况,但我还没有明白。那么我该如何更改代码以使 one.js 中发生的情况立即显示在浏览器中呢?

最佳答案

  1. 您的sleep是一个忙碌的 sleep ,出于各种原因,这是一个坏主意。尤其是在浏览器中的 JavaScript 中,一切都有效地单线程运行。这意味着当您的代码处于“ sleep ”状态时,不会执行任何涉及 JavaScript 的其他内容。

  2. 您的loadScript方法将一个新元素附加到 DOM,这会立即发生。在当前 JavaScript 运行完成之前无法开始执行新脚本,这就是为什么所有脚本都通过 loadScript 加载。只会在您 sleep 后开始运行。

解决此问题的正确方法是接受浏览器中 JavaScript 的事件驱动特性,而不是尝试通过繁忙的循环来“保持运行”。

如果您想“ sleep ”,只需安排新代码稍后运行并从调用中返回即可。

这也会顺便释放 JavaScript 事件循环来处理加载其他脚本之类的事情。

关于javascript - 尝试理解 Javascript 脚本的执行顺序。尝试过异步、延迟、动态加载脚本,但都有不可预测的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61505280/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com