Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Проблема с setTimeout (https://javascript.ru/forum/misc/85950-problema-s-settimeout.html)

HuXT 24.06.2024 12:34

Проблема с setTimeout
 
есть простая страница, которая на вход принимает *.csv и выдаёт *.pdf. сначала есть только кнопка загрузить файл, после загрузки-обработки появляется кнопка скачать пдф, которая запускает библиотеку makePdf и отдаёт готовый файл.
если на вход подаётся небольшой файл, то проблем нет. при увеличении размера страница выглядит подвисшей, даже алерт появляется. поэтому была добавлена промежуточная функция
function runBuildPDF() {
  spinner.classList.add('spinner_shown');
  button.classList.remove('download_shown');
  setTimeout(() => {
    buildPdf()
  }, 10);
}

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

Nexus 24.06.2024 13:27

Вы правда думаете, что проблема в этих 4х строчках кода, а не в том, где и как эта функция вызывается?

HuXT 24.06.2024 13:58

Цитата:

Сообщение от Nexus (Сообщение 555504)
Вы правда думаете, что проблема в этих 4х строчках кода, а не в том, где и как эта функция вызывается?

К сожалению, моих знаний не так много, чтобы делать хоть какие-то выводы. но некоторое кол-во тестов/ проверок показало:
- если убрать setTimeout и вызывать сразу buildPdf(), рестарта страницы нет.
- не имеет значения вызов функции происходит ли <button class="download" type="submit" onclick="runBuildPDF()">Скачать PDF</button>
или
<form class="form" action="#" id="form" onchange="proceedUploadedFile(event)" onSubmit="runBuildPDF()">
Результат тот же.
Удалось понять, что именно добавление setTimeout приводит к рестарту.
Причём проблема появляется только (!!!) при 1ом запуске, все последующие работают как и должны.
Хотелось бы понять корень проблемы.

Nexus 24.06.2024 17:29

Цитата:

Сообщение от HuXT
Хотелось бы понять корень проблемы.

Проблема в том, что вы не предотвращаете поведение формы по умолчанию.
Я, признаться, подобного метода объявления слушателей события (через html-атрибуты) уже давным-давно не видел и не помню как передать событие в слушатель.
Но если предположить, что функция «proceedUploadedFile» корректно получает событие формы в кач-ве аргумента, то вы можете попробовать сделать так:
<form class="form" action="#" id="form" onchange="proceedUploadedFile(event)" onSubmit="runBuildPDF(event)">

function runBuildPDF(event) {
  event.preventDefault()

  spinner.classList.add('spinner_shown');
  button.classList.remove('download_shown');
  setTimeout(() => {
    buildPdf()
  }, 10);
}


Почему у вас форма отправляется только первый раз - непонятно, без кода сложно сказать.


Часовой пояс GMT +3, время: 22:17.