Could using native browser modal dialogs in a loop lead to potentially infinite execution?

时间秒杀一切 提交于 2020-01-06 04:30:26

问题


I was trying some code at JSBin and got weird results. This should work - it's a simple loop that uses Window.prompt. It does execute the correct number of times using Stack Snippets:

for (let i = 0; i < 3; i++) {
  console.log(`i: ${i}`);
  
  let foo = prompt('Enter anyting - it will be echoed.');
  
  console.log(`echo: ${foo}`);
}

Yet on JSBin it only runs for one iteration. If you open the browser console, there is an warning message:

Exiting potential infinite loop at line 1. To disable loop protection: add "// noprotect" to your code

Which made me wonder...what potential infinite loop? To me, there doesn't seem to be anything that can lead to infinite execution. The only "odd" thing about the code is the modal dialog via prompt. I tried using Window.alert:

for (let i = 0; i < 3; i++) {
  console.log(`i: ${i}`);
  
  alert("maximum three alerts");
  let foo = "some input";
  
  console.log(`echo: ${foo}`);
}

And the same thing happens on JSBin as before - single loop executed with the same warning showing in the console.

Removing the modal dialog does lead to the loop executing normally.

for (let i = 0; i < 3; i++) {
  console.log(`i: ${i}`);
  
  let foo = "some input";
  
  console.log(`echo: ${foo}`);
}

So, is the analysis JSBin uses correct that having a modal dialog can lead to an infinite loop and if so - how and when can that happen? Or is this just a false positive?


回答1:


The issue isn't that you're creating an infinite loop using the browser's dialogs, the library JSBin uses to execute your script uses a timeout as a heuristic to check for infinite loops.

Looking in the console, we can see this timeout is defined in runner.js. The GitHub repo for JSBin actually explains how this is done (render.js):

// Rewrite loops to detect infiniteness.
// This is done by rewriting the for/while/do loops to perform a check at
// the start of each iteration.

Unfortunately, I haven't been able to find the code that rewrites the loops, but chances are it rewrites your loop to look something like

let loopStart = Date.now();

for (let i = 0; i < 3; i++) {
  if ((Date.now() - loopStart) >= MAX_LOOP_DURATION) {
    loopProtect.hit();

    break;
  }

  console.log(`i: ${i}`);

  let foo = prompt('Enter anyting - it will be echoed.');

  console.log(`echo: ${foo}`);
}


来源:https://stackoverflow.com/questions/59523031/could-using-native-browser-modal-dialogs-in-a-loop-lead-to-potentially-infinite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!