Adicionar função Timeout / Sleep dentro do loop javascript

Nov 24 2020

Estou tentando adicionar uma função sleep / delay dentro de um arquivo js, ​​este:

var webTest = function()
{

let regex = /^https?:\/\//;
let url = $('#list_urls').val().split('\n');
var xmlhttp = [], i;
var myObj2 = [], i;
 for(let i = 0; i < url.length; i++)
    {
    (function(i) {
    xmlhttp[i] = new XMLHttpRequest();
    url[i] = url[i].replace(regex, '');
    xmlhttp[i].open("GET", "https://website.com/API?key=<MY_API_KEY>&url="+url[i], false);
    xmlhttp[i].onreadystatechange = function() {
      if (xmlhttp[i].readyState === 4 && xmlhttp[i].status === 200) {
        myObj2 = JSON.parse(xmlhttp[i].responseText);
        document.getElementById("demo"+i).innerHTML = myObj2.results[1].categories;
      }
    };
xmlhttp[i].send();
})(i);
console.log(`The Server2: `+ myObj2);
 }
}

Eu quero que este script pause por 10 segundos e depois faça o trabalho novamente e, em seguida, pause novamente por 10 segundos e faça como este até que o comprimento do texto seja maior do que em loop! Meu código funciona se eu executar uma única vez, mas não funciona se eu executar em loop porque o site tem limite de taxa na API, então é por isso que estou tentando adicionar uma função de suspensão.

Então o que tentei é aguardar o sono (); e também tentei o método setTimeout , mas não está funcionando como esperado na classificação, ele não funciona com meu código!

espera dormir (); simplesmente não funciona e exibe msg como Uncaught SyntaxError: await só é válido em funções assíncronas e geradores assíncronos webTestfile.js: 27

Respostas

2 OskarGrosser Nov 25 2020 at 00:10

Você pode usar o async/awaitrecurso do ES6 !

Para usar await, ele precisa estar em um corpo de função / expressão declarado async.

Basicamente, isso fará com que sua função seja assíncrona e espere o Promisecumprimento de um. Fazemos essa promessa ser cumprida após um período definido de uso setTimeout().
Observe que "após um atraso definido" não significa "exatamente depois", basicamente significa "o mais cedo possível depois".

Ao fazer isso, a função assíncrona espera que a promessa seja cumprida, liberando a pilha de chamadas nesse ínterim para que outro código possa ser executado.

A ordem de execução deste exemplo é (simplificada) da seguinte forma:

  1. sleepingFunc() é colocado na pilha de chamadas
    • Em iteração: awaitpara que a promessa seja cumprida, suspender esta chamada 🡒 liberar a pilha de chamadas
  2. Faça novas chamadas na pilha de chamadas
  3. Eventualmente, a promessa é cumprida, terminando await🡒 colocar a chamada suspensa de volta na pilha de chamadas
  4. Repita até sleepingFunc()terminar

Como você pode ver na etapa 3, se outras chamadas demorarem mais do que o atraso, a chamada suspensa terá que esperar esse tempo extra mais.

function sleep(ms) {
  return new Promise(resolveFunc => setTimeout(resolveFunc, ms));
}

async function sleepingFunc() {
  for (let i = 0; i < 5; ++i) {
    console.log(i + " - from sleep");
    await sleep(1000);
  }
}

function synchronousFunc() {
  for (let i = 0; i < 5; ++i) {
    console.log(i + " - from sync");
  }
}

sleepingFunc();
synchronousFunc();

2 Jkarttunen Nov 24 2020 at 22:48

Este snippet de execução executa uma tarefa a cada 1 segundo até que a condição seja satisfeita e, em seguida, limpa o cronômetro.

const work = (i)=>{
 console.log('doing work here ', i);
}

let counter = 0
const timer = setInterval(()=>{
  if (timer && ++counter >= 10) {
   clearInterval(timer)
  }
  work(counter);
}, 1000)