Как прервать цикл внутри функции при перезапуске ее?

Внутри функции цикл, как его прервать при перезапуске функции?

function test(reset){

    for(let i = 0; i < 1000000000; i++){
        if(reset){ break; } 
    }
}

test();

let reset = document.querySelector('.reset');

reset.addEventListener('click', function(){
    test(1);
});

Ответы (2 шт):

Автор решения: SwaD

Для примера, как остановить цикл внутри функции.

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

Так же, допустим при "многопоточности/многоклиентности"(допустим сервер обслуживает пользователей по сокету), для каждого подключения можно создать свои обработчики и управлять ими в рамках текущих сессий.

const counter = document.getElementById('counter');
  const start = document.getElementById('start');
  const stop = document.getElementById('stop');
  const parameter = {};

  function increment(params) {
    const iteration = setInterval(() => {
      counter.innerText = +counter.innerText + 1;
    }, 300);
    params.stop = function () {
      clearInterval(iteration);
      delete params.stop;
    }
  }

  increment(parameter);

  start.addEventListener('click', () => {
    if (!parameter.stop) increment(parameter);
  });

  stop.addEventListener('click', () => {
    if (typeof parameter?.stop === 'function') {
      parameter.stop();
      counter.innerText = '0';
    }
  });
  
  // Пример параллельного запуска
  
  function many() {
    for (let i = 0; i < 10; i++) {
      const param = {}
      const rand = Math.round(Math.random() * 2000);
      increment(param);
      setTimeout(() => {
        if (typeof param?.stop === 'function') {
          param.stop();
          console.log(`Остановлн поток ${i}`);
        }
      }, rand);
    }
  }

  document.getElementById('many').addEventListener('click', many);
<button id="start">Старт</button>
<button id="stop">Стоп</button>
<div id="counter">0</div>
<button id="many">Параллельно</button>

Ну а это классический цикл и способ его прервать через внешнюю переменную

async function sleep() {
    return new Promise(resolve => {
      setTimeout(resolve, 300);
    })
  }

  const counterLoop = document.getElementById('counterLoop');
  const startLoop = document.getElementById('startLoop');
  const stopLoop = document.getElementById('stopLoop');

  let isLoop = true;
  async function iterate() {
    for (let i = 0; i <= 9999; i++) {
      if (!isLoop) break;
      await sleep();
      counterLoop.innerText = +counterLoop.innerText + 1;
    }
    counterLoop.innerText = '0';
  }

  startLoop.addEventListener('click', () => {
    if (!isLoop) {
      isLoop = true;
      iterate();
    }
  })

  stopLoop.addEventListener('click', () => {
    isLoop = false;
  });
  
  iterate();
<button id="startLoop">Старт</button>
<button id="stopLoop">Стоп</button>
<div id="counterLoop">0</div>

→ Ссылка
Автор решения: Вячеслав

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

В итоге получилось такое:

let reset = false;

async function main(){

    let ids = await get_ids();
    
    for (let i = 0; i < ids.length; i += 50) {

        let items = await get_items(ids.slice(i, i + 50));
        if (reset) break;
        
    }

    if(reset){
        reset = false;
        main();
    }
}

main();

let filter_clear = document.querySelector('.filter-clear');

filter_clear.addEventListener('click', function(){
    reset = true;
});

→ Ссылка