在循环中使用本机浏览器模式对话框会导致潜在的无限执行吗? [英] Could using native browser modal dialogs in a loop lead to potentially infinite execution?

查看:101
本文介绍了在循环中使用本机浏览器模式对话框会导致潜在的无限执行吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在JSBin尝试一些代码,但得到了奇怪的结果. 应该有效-这是一个使用

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}`);
}

但是在JSB上只能运行一次迭代.如果打开浏览器控制台,则会出现警告消息:

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

在第1行退出潜在的无限循环.要禁用循环保护,请在代码中添加"//noprotect"

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

这让我想知道...潜在的无限循环是什么?在我看来,似乎没有什么可以导致无限执行.关于代码的唯一奇怪"之处是通过prompt的模式对话框.我尝试使用 Window.alert :

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}`);
}

在JSBin上发生的事情与以前一样-执行了单循环在控制台中显示相同的警告.

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

删除模式对话框会导致循环正常执行.

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

那么,JSBin的分析是否使用了正确的分析,即具有模态对话框可以导致无限循环,如果是这样-怎样以及何时发生?还是只是误报?

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?

推荐答案

问题不在于您正在使用浏览器的对话框创建无限循环,JSBin用于执行脚本的库将超时用作启发式操作,检查无限循环.

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.

在控制台中,我们可以看到此超时是在 runner.js . JSBin的GitHub存储库实际上说明了此操作的完成方式(

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}`);
}

这篇关于在循环中使用本机浏览器模式对话框会导致潜在的无限执行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆