Как остановить выполнение js на странице в браузере

Обновлено: 03.07.2024

Как выйти из сценария JavaScript так же, как PHP exit или die ? Я знаю, что это не лучшая практика программирования, но мне нужно.

JavaScript-эквивалент для die PHP. Кстати, он просто вызывает exit() (спасибо splattne ) :

Я использую оператор return вместо throw, поскольку throw выдает ошибку в консоли. лучший способ сделать это - проверить состояние

Это просто останавливает выполнение программы из этой строки, вместо того, чтобы выдавать какие-либо ошибки в консоли.

Я использую этот кусок кода, чтобы остановить выполнение:

Вы получите ошибку консоли, но она хорошо работает для меня.

Эта небольшая функция довольно близка к имитации выхода PHP (). Как и с другими решениями, больше ничего не добавляйте.

Даже в простых программах без дескрипторов, событий и тому подобного лучше всего поместить код в «основную» функцию, даже если это единственная процедура:

Таким образом, когда вы хотите остановить программу, вы можете использовать «возврат».

Поместите ключевое слово debugger; в код JavaScript, где вы хотите остановить выполнение. Затем откройте инструменты разработчика вашего любимого браузера и перезагрузите страницу. Теперь он должен остановиться автоматически. Откройте раздел Источники своих инструментов: ключевое слово debugger; выделено, и у вас есть возможность возобновить выполнение скрипта.

Я надеюсь, что это помогает.

Дополнительная информация по адресу:

Я думаю, что на этот вопрос был дан ответ, нажмите здесь для получения дополнительной информации. Ниже приведен краткий ответ.

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

Чтобы получить информацию о точках останова Chrome, нажмите здесь
Чтобы получить информацию о точках останова Firefox, нажмите здесь
Для получения информации о точках останова Explorer нажмите
Чтобы получить информацию о точках останова Safari, нажмите здесь.

Если вы ищете способ принудительно прекратить выполнение всего Javascript на странице, я не уверен, что есть официально санкционированный способ сделать это - похоже, что это может быть угрозой безопасности (хотя для честно говоря, я не могу думать о том, как это будет с моей головы). Обычно в Javascript, когда вы хотите, чтобы ваш код прекратил работать, вы просто return выполняете из любой функции. (Оператор return является необязательным, если он является последним в функции и функция не должна возвращать значение). Если по какой-либо причине возврат не достаточно хорош, вам, вероятно, следует отредактировать более подробную информацию в вопросе. почему вы думаете, что вам это нужно, и, возможно, кто-то может предложить альтернативное решение.

Обратите внимание, что на практике интерпретаторы Javascript большинства браузеров просто останавливают текущий скрипт, если они сталкиваются с ошибкой. Таким образом, вы можете сделать что-то вроде доступа к атрибуту неустановленной переменной:

И это вероятно прервет сценарий. Но вы не должны рассчитывать на это, потому что это совсем не стандартно, и это действительно кажется ужасной практикой.

РЕДАКТИРОВАТЬ : ОК, может быть, это был не очень хороший ответ в свете Олафура. Хотя функция die() , с которой он связан, в основном реализует мой второй абзац, то есть просто выдает ошибку.

В JS эквивалентно сигнализировать об ошибке с помощью ключевого слова throw , например:

Вы можете легко проверить это:

Если вам все равно, что это ошибка, просто напишите:

Это остановит ваш основной (глобальный) код. Полезно для некоторых аспектов отладки / тестирования.

Если вы просто хотите остановить выполнение следующего кода без «выдачи» какой-либо ошибки, вы можете временно переопределить window.onerror , как показано в cross-exit :

Это пример того, что, если условие существует, то завершить сценарий. Я использую это в моем клиентском JavaScript SSE, если

Не может быть проанализирован прямо из анализа JSON .

. в любом случае, общая идея такова:

Это прекратит / покрасит ваш скрипт javascript

Бросить "";

Это неправильное использование концепции, но, вероятно, единственный вариант. И, да, вам придется сбросить все прослушиватели событий, как упоминается в принятом ответе. Вам также понадобится одна точка входа, если я прав.

Вдобавок к этому: вам нужна страница, которая сообщает вам по электронной почте, как только она выдается - вы можете использовать, например, Raven / Sentry для этого. Но это значит, что вы производите ложные срабатывания. В таком случае вам также необходимо обновить обработчик по умолчанию, чтобы отфильтровывать такие события или устанавливать такие события на игнорирование на приборной панели Sentry.

Window.stop ( ) ;

Это не работает во время загрузки страницы. Останавливает также декодирование страницы. Таким образом, вы не можете использовать его, чтобы предложить пользователю вариант вашей страницы без использования JavaScript.

Отладчик ;

Останавливает выполнение только при открытом отладчике. Прекрасно работает, но не доставляется.

Если вы используете любую неопределенную функцию в скрипте, тогда скрипт остановится из-за "Uncaught ReferenceError". Я попытался с помощью следующего кода и первые две строки выполнены.

Я думаю, это лучший способ остановить сценарий. Если есть другой способ, пожалуйста, прокомментируйте меня. Я также хочу знать другой лучший и простой способ. Кстати, я не получил выход или умереть встроенную функцию в Javascript, как PHP для завершения сценария. Если кто-то знает, пожалуйста, дайте мне знать.

Существует много способов выйти из сценария JS или Node. Вот наиболее актуальные:

Если вы находитесь в REPL (т.е. после запуска node в командной строке) , вы можете набрать .exit для выхода.

В моем случае я использовал window.stop API, который похож на нажатие кнопки X в вашем браузере:

Просто создайте условие BOOL, здесь нет необходимости в сложном коде.

Если даже если вы включите его в true / или несколько раз, он даст вам одну линию решения / не несколько - в основном просто.

rockon404

Если скрипт зависнет, то FF должен показать вам окно о том, что его надо остановить. Вы можете понизить время ожидания результата выполнения скрипта.

Я не нашёл в гугле как остановить скрипт. Может быть такого и нет, но если вы не знаете, что у вас отъедает CPU, попробуйте занизить время с 10 секунд до, допустим, 5 и запустите ваш скрипт через профайлер, он, возможно, покажет какой код тормозит.

Мне не понятно, что у вас происходит. Цикл может быть бесконечным, это не страшно, страшно, что окно не отвечает - это означает, что не хватает CPU ресурсов и либо вы делаете троттлинг вашего скрипта, либо перекладываете вычислительную работу на кого-либо (сервер, воркер, что у вас там).

Vest, что удивительно, я тоже ничего не нагуглил. Похоже прерывание скрипта невозможно. Вот только не могу понять причин этого, но она наверное должна быть, почему так сделали. Ещё надо заметить, что я использую Vue для интерфейса в браузере. Я не спец, но может это как-то связано с рендером. Типа пока не вернутся вычисления, не может закончить работу с DOM. Но с другой стороны там Virtual DOM.

А я сейчас отлаживаю скрипт, проводящий вычисления на клиенте. Там довольно навороченный рекурсивный алгоритм. Отлаживаю и. иногда он не выходит из рекурсии, всё зависает. Приходится закрывать окно, а потом заново всё открывать. Но скрипт на самом деле очень быстрый (если правильно работает), т.е. сложный алгоритмически, но не загрузный по времени. Воркеры или сервер не нужен.

За ссылочку про понижение времени — спасибо.

Николай Чуприк, меня закидают тапками, но я думаю, что всё дело в однопоточности JavaScript или конкретной вкладки. Когда у вас единственный поток занят рекурсивными вычислениями, то у него нет эдакого кванта времени, чтобы обработать ещё нажатие несуществующей кнопки Stop в вашем отладчике. Наверняка, это всё крутится в одном потоке, а если и нет, то возможно этот поток не отпущен браузером, чтобы принять вашу команду.

Я бы предложил вам добавить проверку на некоторую глобальную переменную, и если она "true", выйти из рекурсии, но смешно то, что JavaScript-консоль скорее всего зависнет и вы не сможете в ней выставить вашу переменную в "true"
¯\_(ツ)_/¯

Vest, JS поток конечно один, но для JS браузер является супервизором. Мне не понятно, почему он не может его тормознуть. Или кнопки Developer Tools реализованы в том же потоке JS :). Странно конечно.

Мне сейчас приходится ставить в рекурсию окно confirm('Стоп?'), и пока долбишь "нет", рекурсия продолжается, что неудобно. Причём если ставить breakpoint в рекурсивную функцию, то я могу всего лишь остановить выполнение скрипта, но не прервать его. После breakpoint у меня выбора нет, могу только продолжить выполнение, даже если понимаю, что это уход рекурсии в нирвану.

Николай Чуприк, хорошая идея. Пусть у вас будет счётчик в рекурсии. Вы будете каждый раз его увеличивать, когда куда-либо проваливаетесь. Как наберёте 100 вызовов - показываете confirm, а потом ещё раз 100 циклов и т. д.

Давайте отвлечёмся от написания кода и поговорим о его отладке.

Отладка – это процесс поиска и исправления ошибок в скрипте. Все современные браузеры и большинство других сред разработки поддерживают инструменты для отладки – специальный графический интерфейс, который сильно упрощает отладку. Он также позволяет по шагам отследить, что именно происходит в нашем коде.

Мы будем использовать браузер Chrome, так как у него достаточно возможностей, в большинстве других браузеров процесс будет схожим.

Панель «Исходный код» («Sources»)

Версия Chrome, установленная у вас, может выглядеть немного иначе, однако принципиальных отличий не будет.

  • Работая в Chrome, откройте тестовую страницу.
  • Включите инструменты разработчика, нажав F12 (Mac: Cmd + Opt + I ).
  • Щёлкните по панели sources («исходный код»).

При первом запуске получаем следующее:

Кнопка-переключатель откроет вкладку со списком файлов.

Кликните на неё и выберите hello.js . Вот что появится:

Интерфейс состоит из трёх зон:

  1. В зоне Resources (Ресурсы) показаны файлы HTML, JavaScript, CSS, включая изображения, используемые на странице. Здесь также могут быть файлы различных расширений Chrome.
  2. Зона Source показывает исходный код.
  3. Наконец, зона Information and control (Сведения и контроль) отведена для отладки, вскоре мы к ней вернёмся.

Чтобы скрыть список ресурсов и освободить экранное место для исходного кода, щёлкните по тому же переключателю .

Консоль

При нажатии на клавишу Esc в нижней части экрана вызывается консоль, где можно вводить команды и выполнять их клавишей Enter .

Результат выполнения инструкций сразу же отображается в консоли.

Например, результатом 1+2 будет 3 , а инструкция hello("debugger") ничего не возвращает, так что получаем undefined :

Точки останова (breakpoints)

Давайте разберёмся, как работает код нашей тестовой страницы. В файле hello.js щёлкните по строчке номер 4 . Да, щёлкайте именно по самой цифре, не по коду.

Ура! Вы поставили точку останова. А теперь щёлкните по цифре 8 на восьмой линии. Номер строки будет окрашен в синий цвет.

Вот что в итоге должно получиться:

Точка останова – это участок кода, где отладчик автоматически приостановит исполнение JavaScript.

Пока исполнение поставлено «на паузу», мы можем просмотреть текущие значения переменных, выполнить команды в консоли, одним словом, мы выполняем отладку кода.

В правой части графического интерфейса мы видим список точек останова. А когда таких точек выставлено много, да ещё и в разных файлах, этот список поможет эффективно ими управлять:

  • Быстро переместиться к любой точке останова в коде – нужно щёлкнуть по точке в правой части экрана.
  • Временно деактивировать точку – в общем списке снимите галочку напротив ненужной в данный момент точки.
  • Удалить точку – щёлкните по ней правой кнопкой мыши и выберите Remove (Удалить).
  • …и так далее.

Можно задать и так называемую условную точку останова – щёлкните правой кнопкой мыши по номеру строки в коде. Если задать выражение, то именно при его истинности выполнение кода будет приостановлено.

Этот метод используется, когда выполнение кода нужно остановить при присвоении определённого выражения какой-либо переменной или при определённых параметрах функции.

Команда Debugger

Выполнение кода можно также приостановить с помощью команды debugger прямо изнутри самого кода:

Способ удобен тем, что можно продолжить работать в редакторе кода без необходимости переключения в браузер для выставления точки останова.

Остановимся и оглядимся

В нашем примере функция hello() вызывается во время загрузки страницы, поэтому для начала отладки (после того, как мы поставили точки останова) проще всего её перезагрузить. Нажмите F5 (Windows, Linux) или Cmd + R (Mac).

Выполнение прервётся на четвёртой строчке:

Чтобы понять, что происходит в коде, щёлкните по стрелочкам справа:

Watch показывает текущие значения выражений.

Нажмите на + и введите выражение. В процессе выполнения отладчик автоматически пересчитывает и выводит его значение.

Call Stack показывает последовательность вызовов функций.

В нашем примере отладчик работает с функцией hello() , вызванной скриптом из файла index.html (там нет функции, поэтому вызов «анонимный»).

При нажатии на элемент списка (например, на «anonymous») отладчик переходит к соответствующему коду, и нам представляется возможность его проанализировать.

Scope показывает текущие переменные.

В Local отображаются локальные переменные функций, а их значения подсвечены в исходном коде.

В Global перечисляются глобальные переменные (т.е. объявленные за пределами функций).

Не обращайте пока внимание на ключевое слово this – его мы изучим чуть позже.

Пошаговое выполнение скрипта

А теперь давайте пошагаем по нашему коду.

В правой части панели для этого есть несколько кнопок. Рассмотрим их.

– продолжить выполнение. Быстрая клавиша – F8 .

Возобновляет выполнение кода. Если больше нет точек останова, отладчик прекращает работу и позволяет приложению работать дальше.

Вот, что мы увидим, кликнув на неё:

Выполнение кода возобновилось, дошло до другой точки останова внутри say() , и отладчик снова приостановил выполнение. Обратите внимание на пункт «Call stack» справа: в списке появился ещё один вызов. Мы теперь внутри функции say() .

– сделать шаг (выполнить следующую команду), не заходя в функцию. Быстрая клавиша – F10 .

Если мы нажмём на неё – будет вызван alert . Важно: на месте alert может быть любая другая функция, выполнение просто перешагнёт через неё, полностью игнорируя её содержимое.

– сделать шаг. Быстрая клавиша – F11 .

В отличие от предыдущего примера, здесь мы «заходим» во вложенные функции и шаг за шагом проходим по скрипту.

– продолжить выполнение до завершения текущей функции. Быстрая клавиша – Shift + F11 .

Выполнение кода остановится на самой последней строчке текущей функции. Этот метод применяется, когда мы случайно нажали и зашли в функцию, но нам она неинтересна и мы как можно скорее хотим из неё выбраться.

– активировать/деактивировать все точки останова.

Эта кнопка не влияет на выполнение кода, она лишь позволяет массово включить/отключить точки останова.

– разрешить/запретить остановку выполнения в случае возникновения ошибки.

Если опция включена и инструменты разработчика открыты, любая ошибка в скрипте приостанавливает выполнение кода, что позволяет его проанализировать. Поэтому если скрипт завершается с ошибкой, открываем отладчик, включаем эту опцию, перезагружаем страницу и локализуем проблему.

Если щёлкнуть правой кнопкой мыши по строчке кода, в контекстном меню можно выбрать опцию «Continue to here» («продолжить до этого места»).

Этот метод используется, когда нам нужно продвинуться на несколько шагов вперёд до нужной строки, но лень выставлять точки останова.

Логирование

Если нужно что-то вывести в консоль из кода, применяется функция console.log .

К примеру, выведем в консоль значения от нуля до четырёх:

Обычный пользователь сайта не увидит такой вывод, так как он в консоли. Напомним, что консоль можно открыть через инструменты разработчика – выберите вкладку «Консоль» или нажмите Esc , находясь в другой вкладке – консоль откроется в нижней части интерфейса.

Если правильно выстроить логирование в приложении, то можно и без отладчика разобраться, что происходит в коде.

Итого

Приостановить выполнение скрипта можно тремя способами:

  1. Точками останова.
  2. Использованием в коде команды debugger .
  3. При ошибке (если инструменты разработчика открыты и опция включена).

При остановке мы можем отлаживать – проанализировать переменные и пошагово пройти по процессу, что поможет отыскать проблему.

Для простой отладки вполне достаточно сведений из этой главы, но в дальнейшем рекомендуем вам изучить официальное руководство, если вы собираетесь разрабатывать для браузеров.

И, конечно, вы можете просто покликать в разных местах инструментов разработчика. Пожалуй, это наискорейший способ ими овладеть. Не забывайте про правый клик мыши и контекстные меню!

Мы можем вызвать функцию не в данный момент, а позже, через заданный интервал времени. Это называется «планирование вызова».

Для этого существуют два метода:

  • setTimeout позволяет вызвать функцию один раз через определённый интервал времени.
  • setInterval позволяет вызывать функцию регулярно, повторяя вызов через определённый интервал времени.

Эти методы не являются частью спецификации JavaScript. Но большинство сред выполнения JS-кода имеют внутренний планировщик и предоставляют доступ к этим методам. В частности, они поддерживаются во всех браузерах и Node.js.

setTimeout

func|code Функция или строка кода для выполнения. Обычно это функция. По историческим причинам можно передать и строку кода, но это не рекомендуется. delay Задержка перед запуском в миллисекундах (1000 мс = 1 с). Значение по умолчанию – 0. arg1 , arg2 … Аргументы, передаваемые в функцию (не поддерживается в IE9-)

Например, данный код вызывает sayHi() спустя одну секунду:

Если первый аргумент является строкой, то JavaScript создаст из неё функцию.

Это также будет работать:

Но использование строк не рекомендуется. Вместо этого используйте функции. Например, так:

Начинающие разработчики иногда ошибаются, добавляя скобки () после функции:

Это не работает, потому что setTimeout ожидает ссылку на функцию. Здесь sayHi() запускает выполнение функции, и результат выполнения отправляется в setTimeout . В нашем случае результатом выполнения sayHi() является undefined (так как функция ничего не возвращает), поэтому ничего не планируется.

Отмена через clearTimeout

Вызов setTimeout возвращает «идентификатор таймера» timerId , который можно использовать для отмены дальнейшего выполнения.

Синтаксис для отмены:

В коде ниже планируем вызов функции и затем отменяем его (просто передумали). В результате ничего не происходит:

Как мы видим из вывода alert , в браузере идентификатором таймера является число. В других средах это может быть что-то ещё. Например, Node.js возвращает объект таймера с дополнительными методами.

Повторюсь, что нет единой спецификации на эти методы, поэтому такое поведение является нормальным.

Для браузеров таймеры описаны в разделе таймеров стандарта HTML5.

setInterval

Метод setInterval имеет такой же синтаксис как setTimeout :

Все аргументы имеют такое же значение. Но отличие этого метода от setTimeout в том, что функция запускается не один раз, а периодически через указанный интервал времени.

Чтобы остановить дальнейшее выполнение функции, необходимо вызвать clearInterval(timerId) .

В большинстве браузеров, включая Chrome и Firefox, внутренний счётчик продолжает тикать во время показа alert/confirm/prompt .

Рекурсивный setTimeout

Есть два способа запускать что-то регулярно.

Один из них setInterval . Другим является рекурсивный setTimeout . Например:

Метод setTimeout выше планирует следующий вызов прямо после окончания текущего (*) .

Рекурсивный setTimeout – более гибкий метод, чем setInterval . С его помощью последующий вызов может быть задан по-разному в зависимости от результатов предыдущего.

Например, необходимо написать сервис, который отправляет запрос для получения данных на сервер каждые 5 секунд, но если сервер перегружен, то необходимо увеличить интервал запросов до 10, 20, 40 секунд… Вот псевдокод:

А если функции, которые мы планируем, ресурсоёмкие и требуют времени, то мы можем измерить время, затраченное на выполнение, и спланировать следующий вызов раньше или позже.

Рекурсивный setTimeout позволяет задать задержку между выполнениями более точно, чем setInterval .

Сравним два фрагмента кода. Первый использует setInterval :

Второй использует рекурсивный setTimeout :

Для setInterval внутренний планировщик будет выполнять func(i) каждые 100 мс:

Реальная задержка между вызовами func с помощью setInterval меньше, чем указано в коде!

Это нормально, потому что время, затраченное на выполнение func , использует часть заданного интервала времени.

Вполне возможно, что выполнение func будет дольше, чем мы ожидали, и займёт более 100 мс.

В данном случае движок ждёт окончания выполнения func и затем проверяет планировщик и, если время истекло, немедленно запускает его снова.

В крайнем случае, если функция всегда выполняется дольше, чем задержка delay , то вызовы будут выполняться без задержек вообще.

Ниже представлено изображение, показывающее процесс работы рекурсивного setTimeout :

Рекурсивный setTimeout гарантирует фиксированную задержку (здесь 100 мс).

Это потому, что новый вызов планируется в конце предыдущего.

Когда функция передаётся в setInterval/setTimeout , на неё создаётся внутренняя ссылка и сохраняется в планировщике. Это предотвращает попадание функции в сборщик мусора, даже если на неё нет других ссылок.

Для setInterval функция остаётся в памяти до тех пор, пока не будет вызван clearInterval .

Есть и побочный эффект. Функция ссылается на внешнее лексическое окружение, поэтому пока она существует, внешние переменные существуют тоже. Они могут занимать больше памяти, чем сама функция. Поэтому, если регулярный вызов функции больше не нужен, то лучше отменить его, даже если функция очень маленькая.

setTimeout с нулевой задержкой

Особый вариант использования: setTimeout(func, 0) или просто setTimeout(func) .

Это планирует вызов func настолько быстро, насколько это возможно. Но планировщик будет вызывать функцию только после завершения выполнения текущего кода.

Так вызов функции будет запланирован сразу после выполнения текущего кода.

Например, этот код выводит «Привет» и затем сразу «Мир»:

Первая строка помещает вызов в «календарь» через 0 мс. Но планировщик проверит «календарь» только после того, как текущий код завершится. Поэтому "Привет" выводится первым, а "Мир" – после него.

Есть и более продвинутые случаи использования нулевой задержки в браузерах, которые мы рассмотрим в главе Событийный цикл: микрозадачи и макрозадачи.

Минимальная задержка вложенных таймеров в браузере

В браузере есть ограничение на то, как часто внутренние счётчики могут выполняться. В стандарте HTML5 говорится: «после пяти вложенных таймеров интервал должен составлять не менее четырёх миллисекунд.».

Продемонстрируем в примере ниже, что это означает. Вызов setTimeout повторно вызывает себя через 0 мс. Каждый вызов запоминает реальное время от предыдущего вызова в массиве times . Какова реальная задержка? Посмотрим:

Первый таймер запускается сразу (как и указано в спецификации), а затем задержка вступает в игру, и мы видим 9, 15, 20, 24. .

Аналогичное происходит при использовании setInterval вместо setTimeout : setInterval(f) запускает f несколько раз с нулевой задержкой, а затем с задержкой 4+ мс.

Это ограничение существует давно, многие скрипты полагаются на него, поэтому оно сохраняется по историческим причинам.

Этого ограничения нет в серверном JavaScript. Там есть и другие способы планирования асинхронных задач. Например, setImmediate для Node.js. Так что это ограничение относится только к браузерам.

Итого

  • Методы setInterval(func, delay, . args) и setTimeout(func, delay, . args) позволяют выполнять func регулярно или только один раз после задержки delay , заданной в мс.
  • Для отмены выполнения необходимо вызвать clearInterval/clearTimeout со значением, которое возвращают методы setInterval/setTimeout .
  • Вложенный вызов setTimeout является более гибкой альтернативой setInterval . Также он позволяет более точно задать интервал между выполнениями.
  • Планирование с нулевой задержкой setTimeout(func,0) или, что то же самое, setTimeout(func) используется для вызовов, которые должны быть исполнены как можно скорее, после завершения исполнения текущего кода.
  • Браузер ограничивает 4-мя мс минимальную задержку между пятью и более вложенными вызовами setTimeout , а также для setInterval , начиная с 5-го вызова.

Обратим внимание, что все методы планирования не гарантируют точную задержку.

Например, таймер в браузере может замедляться по многим причинам:

  • Перегружен процессор.
  • Вкладка браузера в фоновом режиме.
  • Работа ноутбука от аккумулятора.

Всё это может увеличивать минимальный интервал срабатывания таймера (и минимальную задержку) до 300 или даже 1000 мс в зависимости от браузера и настроек производительности ОС.

Задачи

Вывод каждую секунду

Напишите функцию printNumbers(from, to) , которая выводит число каждую секунду, начиная от from и заканчивая to .

Читайте также: