在页面完全加载之前提示执行并阻止console.log

问题描述 投票:0回答:1

我有一个有趣的问题。

我在JS中有一个提示。当我进入页面时,提示会立即执行并阻止 console.logs。在提示中执行一些逻辑后,当我关闭提示时,所有 console.logs 立即显示在控制台中。而且只有当我第一次加入该页面时才会发生这种情况。下次所有 console.log 都工作正常。我的问题,但我不知道解决方案。我认为这就是浏览器和js的工作方式。这里没有解决办法。

let userAnswer = "";
let contvertedStr = "";

while (true) {
  const type = prompt(
    "Program – Main Menu \nPlease enter 1, 2, 3, or exit."
  ).toLowerCase();

  if (type === "1") {
    while (!userAnswer) {
      userAnswer = prompt("Please enter a string.");

      if (!userAnswer) {
        console.log("You need to enter something");
      }
    }
  }

  if (type === "2") {
    if (!userAnswer) {
      console.log("You need to first enter a String");
      continue;
    }

    const splitString = userAnswer.split(" ");
    let newArray = [];

    for (const str of splitString) {
      if (str.length >= 5) {
        newArray.push(str + "-bonk");
      } else {
        newArray.push(str + "-bink");
      }
    }

    contvertedStr = newArray.join(" ");

    console.log("String converted");
  }

  if (type === "3") {
    if (contvertedStr) {
      console.log(contvertedStr);

      userAnswer = "";
      contvertedStr = "";

      continue;
    } else {
      console.log("You need to first convert your String");
      continue;
    }
  }

  if (type === "exit") {
    console.log("Thanks for using the ROBOT Language Converter!");
    break;
  }
}

我尝试了 DOMContentloaded、window.onload、async、defer 等,但没有成功

javascript asynchronous prompt
1个回答
0
投票

while (true) {

除非在

async
循环中使用,否则这对于 Javascript 来说绝不是一个好主意,当主事件循环不断阻塞时控制台的行为可能是未定义的行为,不应该是您依赖的东西。

现在有2种简单的方法可以解决这个问题,

  1. 使用
    setTimeout
    继续循环。
  2. 使用上面指出的
    async
    循环。

function doLoop() {
  const r = prompt('type x to quit').toLowerCase();
  console.log(`you typed ${r}`);
  if (r !== 'x') 
    setTimeout(doLoop);
}

doLoop();  //lets start the loop

所以基本上在上面我们只是用

continue
替换
setTimeout(doLoop)

现在对于选项 2,使用

async
循环,从长远来看这是更好的选择,因为它更容易扩展。

const breath = () => new Promise(resolve => setTimeout(resolve));

async function doLoop() {
  while (true) {
    await breath();
    const r = prompt('type x to quit').toLowerCase();
    console.log(`you typed ${r}`);
    if (r === 'x') break;
  }
}

doLoop();  //lets start the loop

现在在上面你可以看到我们已经使用了

while (true) {
,但是这里的技巧是,当你这样做时,你需要允许事件循环运行,这就是
breath
函数正在做的事情。
prompt
函数仍然会阻塞,但是那些
breath
只会为事件循环留出一些时间。

当然更好的是首先不使用

prompt
,现在大多数 GUI 库都具有执行对话框的功能,不仅使这些循环更好,它们也不会像
alert
/
prompt
那样阻塞浏览器等等。

© www.soinside.com 2019 - 2024. All rights reserved.