Home > Software engineering >  How can i pause a map or loop of array using setTimeout in javascript?
How can i pause a map or loop of array using setTimeout in javascript?

Time:12-08

 data.map((d, i) => {
        setTimeout(() => {
          drawCanvas(canvasRef, d);
        }, 1000 * i);
      });

i applied loop on array using map with a delay of one second now i want to add a pause or resume function on this loop. Is it possible to perform anything like this?or any other solution

CodePudding user response:

You can use async/await to "sleep" for a given duration; using a Promise.

const sleep = async (ms) => new Promise(res => setTimeout(res, ms));

(async () => {
  for (let i = 0; i < data.length; i  ) {
    await sleep(1000); // Sleep for 1 second between
    drawCanvas(canvasRef, data[i]);
  }
})();

Working example

const
  sleep = async (ms) => new Promise(res => setTimeout(res, ms)),
  canvasRef = { current: document.querySelector('#drawing') };

const drawCanvas = (canvasRef, conf) => {
  const ctx = canvasRef.current.getContext('2d');
  ctx.fillStyle = conf.color;
  ctx.beginPath();
  switch (conf.kind) {
    case 'circle':
      ctx.arc(conf.x, conf.y, conf.radius, 0, 2 * Math.PI);
      break;
    case 'rectangle':
      ctx.fillRect(conf.x, conf.y, conf.width, conf.height);
      break;
    case 'triangle':
      ctx.moveTo(conf.x, conf.y);
      ctx.lineTo(conf.x, conf.y   conf.height);
      ctx.lineTo(conf.x   conf.width, conf.y   conf.height);
      break;
  }
  ctx.closePath();
  ctx.fill();
};

const data = [
  { kind: 'rectangle', x: 30, y: 40, width: 140, height: 30, color: 'blue' },
  { kind: 'rectangle', x: 80, y: 20, width: 50, height: 20, color: 'blue' },
  { kind: 'triangle', x: 130, y: 20, width: 20, height: 20, color: 'blue' },
  { kind: 'circle', x: 70, y: 70, radius: 16, color: 'red' },
  { kind: 'circle', x: 130, y: 70, radius: 16, color: 'red' },
];

Object.assign(canvasRef.current, { width: 200, height: 100 });

(async () => {
  for (let i = 0; i < data.length; i  ) {
    await sleep(1000); // Sleep for 1 second between
    drawCanvas(canvasRef, data[i]);
  }
})();
#drawing { border: thin solid grey; }
<canvas id="drawing"></canvas>

CodePudding user response:

You can't pause a map, because it's sync in nature, modern JS has something called async / await that makes doing this simply.

Pausing can be accomplished by using a Promise constructor that you can manually resolve based on some event, eg. checkbox click etc.

Below is a simple example that counts from one to ten in an infinite loop, that you can then pause / resume by checking the checkbox.

const numbers = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];

const sleep = ms => new Promise(r => setTimeout(r,ms));
const elNum = document.querySelector('#num');
const elInput = document.querySelector('input');

let pause = Promise.resolve();

const pauseClick = cb => 
  elInput.addEventListener('click', cb, {once: true});

function checkForPause() {   
  pauseClick(() => {
    pause = new Promise(resolve => {
      pauseClick(() => { resolve(); checkForPause();});
    });
  });
}

checkForPause();

async function run() {
  while (true) {
    for (const num of numbers) {
      elNum.innerText = num;
      await sleep(1000);
      await pause;
    }
  }
}

run();
#num {
  font-size: 20pt;
}
Pause: <input type="checkbox"/>


<div id="num">....</div>

  • Related