Як зупинити нескінченний цикл у Javascript?


77

Скажімо, я випадково написав це:

 do { } while (true);

... а потім запустив його. Окрім вбивства вашого браузера, чи є спосіб зупинити виконання javascript (еквівалент Ctrl + Break в основному або Ctrl + C)?

Зазвичай, приблизно через 30 секунд ваш браузер запитує, чи хочете ви зупинити тривалий сценарій, але це не завжди трапляється (як я щойно дізнався)!

FYI: Простий цикл, такий як цей: for (i=1; i > 0; ++i);спричинить збій мого браузера (Firefox 3.5b4). Я не дуже люблю тестувати, щоб перевірити, чи це якийсь із моїх доповнень. Постійний перезапуск браузера - це не моя ідея веселого вечора в понеділок.


З цікавості ви змогли визначити, що змусило ваш браузер не видавати попередження про "повільний сценарій"?
alex

2
жодної підказки! (це обмеження в 15 символів дратує)
nickf

Це належить до SuperUser?
Четан

3
@Chetan: Це майже повністю пов'язано з програмуванням ...
nickf

О, я неправильно зрозумів це як питання про використання браузера, а не як про розробку плагінів. Моє ліжко.
Четан

Відповіді:


23

Принаймні за допомогою Chrome, можливо, вам вдасться вимкнути окрему вкладку, а не всю програму.

Рендолфо також повідомив мені, що IE8 має подібну функціональність.


3
Чи можете ви детальніше розповісти про те, як вбити одну вкладку? Чи шукаємо ми правильний chrome.exe і вбиваємо його в диспетчері завдань?
mellamokb

1
заперечний, не працює! принаймні не у версії 36.0.1985.125 для Linux
Octopus

2
У мене це працювало у версії 40.0.2214.115 (64-розрядна), але мені довелося почекати кілька секунд. Ця відповідь була б 10-разовою корисною та придатною для голосування, якби вона включала ці деталі.
Michael Scheper

1
Я виявив, що це спрацювало для мене, однак, якщо ви натиснете shift + esc на тій самій вкладці, де є нескінченний цикл, Chrome дасть javascript можливість обробити натискання клавіші / клавіатуру / клавіатуру, перш ніж вирішити, чи повинен він щось робити, оскільки ваш javascript зайнятий і не може обробити події, які ви фактично вимикаєте всі ярлики Chrome.
Барак Галл,

У Chrome я відкриваю нову вкладку і двічі клацнув xкнопку за назвою вкладки. Здається, це працює, хоча я не впевнений, чому перший клік не зареєстрований.
Програми

58

Я використовую Chome версії 45.0.2454.101

У верхньому правому куті, у меню гамбургера, натисніть Додаткові інструменти> Диспетчер завдань, а потім вбийте вкладку звідти. Це якщо спроба закрити вкладку не вдається. В іншому випадку просто "X" на вкладці вбиває його.


наявність нескінченного циклу в зворотному виклику Ajax призводить до збою простого X, коли у вас відкриті інструменти devtools.
masterX244

54

2018 оновлення:

У Chrome 67, якщо у вас відкриті DevTools ( F12), ви можете закінчити нескінченний цикл, не вбиваючи всю вкладку:

  • Перейдіть на панель Джерела та натисніть "Призупинити виконання сценарію".
  • Утримуйте ту саму кнопку і тепер виберіть значок "Зупинити".

введіть тут опис зображення

https://developers.google.com/web/updates/2018/04/devtools#stop


Це не спрацювало для мене, хоча, можливо, з усіма матеріалами у джерелах, я просто не можу знайти потрібний файл.
TiggerToo

@TiggerToo - Спочатку не потрібно знаходити потрібний файл. Просто натисніть кнопку паузи, і браузер зупиниться там, де він застряг.
Sphinxxx

10

посилання: /superuser/92617/stop-never-ending-popup-alerts-in-firefox
Firefox особливо проблематичний ...

Увага! Попередження! НЕ запускайте це!

javascript:
    while (true) alert("irritated and exhausted - yet?");

Це буде "нескінченно" і НЕ буде вичерпувати внутрішній тайм-аут, оскільки сценарій не буде перегрівати час процесора досить швидко. У FF 11 це гарантує відсутність можливості переривання вагітності за сценарієм, що не відповідає.

Витончено зупинити лише скривдливий сценарій було можливим і тривіальним у ранніх версіях браузера, використовуючи ручне втручання, без каркання та переривання всього браузера. Не мати такого контролю - головна вада дизайну програмного забезпечення браузера. Необхідні спритні спритність і рефлекси необхідні для впливу на ручну механіку двигуна "рішень", описаних у посиланні.

Увага: сценарії можуть переходити в режим "нескінченно" без тайм-ауту І без запитів типу попередження. Це особливо згубно і надокучливо. В основному, сценарії працюють досить повільно, так що розподіл часового циклу процесора становить приблизно 20 секунд. розтягується на декілька хвилин або годин або ..., перед тимчасовим тайм-актом, шляхом призупинення виконання до відновлення тригера події. Замість того, щоб синхронізувати цикли процесора, для скриптів було б набагато кращому тайм-аут для реального часу. (Ви коли-небудь помічали, як ви не можете перервати сценарій, який намагається отримати вміст - але невдало - для побудови сторінки? У FF і кнопки адресного рядка, reloadі кнопки cancel/stopвимкнені, хоча вкладку принаймні можна закрити.) Звичайний javascript Timeout()іsetInterval() дзвінки не страждають від цього і зумовлені таким чином, що, коли призупинено, ручне втручання може перервати їх "витончено".

Тестове середовище для емпіричних спостережень:

window.navigator.userAgent=
Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:11.0) Gecko/20100101 Firefox/11.0

PS. сценарій

for (i=1; i > 0; ++i);

врешті-решт уловлює помилку переповнення, коли iперевищує максимально допустиме значення.


9

Якщо ви використовуєте Chrome, ви можете легко вбити вкладку, яка не відповідає.

Коли ви побачите нескінченний цикл JavaScript, виконайте такі дії:

1.Якщо ви вже відкрили іншу вкладку, перейдіть на неї або відкрийте нову

2.Натисніть "Shift + Esc", щоб відкрити диспетчер завдань Chrome

3.Знайдіть свою вкладку у списку (має бути з найбільшою кількістю споживачів пам'яті у списку) та натисніть кнопку "Завершити процес".


Перехід до іншої вкладки є важливим, оскільки JavaScript зафіксує натискання вашої клавіші і нічого на цьому не зробить через нескінченний цикл.


4

У більшості браузерів є попередження про "повільну продуктивність сценарію", яке з'являється, коли виконуваному неконтрольованому javascript потрібно дуже багато часу. У цьому діалоговому вікні попередження зазвичай надається можливість вбити скрипт, що порушує право.


5
-1 надлишковий. OP: "Зазвичай, приблизно через 30 секунд ваш браузер запитує, чи хочете ви зупинити тривалий сценарій, але це не завжди трапляється (як я щойно дізнався)!" Я теж зазнав тієї ж проблеми, оскільки діалогове вікно не завжди відображалося.
mellamokb

Дивіться stackoverflow.com/questions/905322/… з можливою причиною, чому "діалогове вікно відображається не завжди".
user66001

4

Залежить від браузера. Деякі дозволяють натиснути кнопку "зупинити", щоб зупинити виконання JavaScript. Інші ні.

Я вважаю, що найкращий спосіб - це просто вбити браузер або вкладку повністю.


0

більшість пристойних браузерів показують попередження про "сценарій, що не відповідає" ... Якщо ні, то, мабуть, найкращим способом буде виявити, чому попередження не з’являється.


0

З /superuser/92617/stop-never-ending-popup-alerts-in-firefox#comment93927_92617 , анонімно :

Це не є задовільним рішенням загального призначення, але за допомогою Greasmonkey (або, можливо, Ubiquity або Jetpack), ви можете переписати window.alert функцією, яка викликає window.confirm і, за бажанням, викинути помилку, зупинивши виконання всіх сценаріїв, або перемикає прапор, щоб зупинити попередження. Це може бути корисно, якщо сайт, на який ви постійно повертаєтесь, представляє таку поведінку.


0

Що я роблю під час використання Chrome, і це трапляється, натискаю клавіші Shift + Ctrl + Esc, щоб відкрити менеджер завдань Windows. Потім перейдіть на вкладку процеси та прокрутіть процеси chrome.exe (у chrome є один процес на кожну відкриту вкладку), поки я не знайду такий із значно більшим використанням процесора, ніж інші. Це, як правило, становить близько 30% для мене, тоді як усі інші мають приблизно 0-2%. Тоді я просто закінчу цей процес. Насправді те ж саме можна зробити, перейшовши до tools> taskmanager або shift + esc в chrome, щоб відкрити власний диспетчер завдань для його процесів. Може бути простішим у використанні, оскільки він відображає більше інформації про вкладки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.