【问题标题】:Add Timeout / Sleep function inside javascript loop在javascript循环中添加超时/睡眠功能
【发布时间】:2021-03-07 18:57:42
【问题描述】:

我正在尝试在 js 文件中添加睡眠/延迟功能,这个:

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);
 }
}

我希望此脚本暂停 10 秒,然后再次执行工作,然后再次暂停 10 秒并这样做,直到文本长度大于循环中的 i!如果我单次运行,我的代码可以工作,但如果我在循环中运行,它就不起作用,因为 websiteapi 中有速率限制,所以这就是我尝试的原因添加睡眠功能。

所以我尝试的是 await sleep(); 方法,也尝试了 setTimeout 方法,但它没有按预期工作,它根本不起作用用我的代码!

等待睡眠();只是根本不起作用并显示味精 未捕获的 SyntaxError:await 仅在异步函数和异步生成器 webTestfile.js:27 中有效

【问题讨论】:

  • 我希望此脚本暂停 10 秒,然后再次执行工作,然后再次暂停 10 秒! 您不能暂停代码。您可以做的是在延迟后运行更多代码,但调用堆栈上当前正在运行的函数必须在任何新代码开始之前完成。
  • 是的,我知道 javascript 没有任何睡眠功能,但是在这里可以做些什么来实现至少 10-11 秒的延迟?尝试了 setTimeout 方法,但没有任何效果:/
  • 这个答案显示sleep()-alternative for JS in ES6

标签: javascript arrays json xmlhttprequest


【解决方案1】:

你可以make use of ES6's async/await-feature

要使用await,它需要位于声明async的函数/表达式主体中。

基本上,这将使您的函数异步,并使其等待Promise 被执行。我们使用 setTimeout() 使 Promise 在设定的延迟后实现。
注意“在设定的延迟之后”并不意味着“恰好在之后”,它基本上意味着“尽可能早地之后”。

通过这样做,异步函数等待承诺被履行,同时释放调用堆栈,以便执行其他代码。

本例的执行顺序(简化)如下:

  1. sleepingFunc() 被放置在调用栈中
    • 在迭代中:await 用于实现 Promise,暂停此调用 ? 释放调用堆栈
  2. 在调用堆栈上进行新调用
  3. 最终,Promise 实现,结束 await ? 在调用堆栈上放置暂停回调
  4. 重复直到sleepingFunc() 完成

正如您在第 3 步中看到的,如果其他呼叫占用的时间超过延迟时间,则暂停的呼叫将不得不等待更长的时间。

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】:

    这运行 sn -p 每 1 秒运行一个任务,直到满足条件,然后清除计时器。

    const work = (i)=>{
     console.log('doing work here ', i);
    }
    
    let counter = 0
    const timer = setInterval(()=>{
      if (timer && ++counter >= 10) {
       clearInterval(timer)
      }
      work(counter);
    }, 1000)

    【讨论】:

      猜你喜欢
      • 2018-01-19
      • 1970-01-01
      • 2013-01-13
      • 2021-08-29
      • 1970-01-01
      • 2019-10-21
      • 2017-06-25
      • 1970-01-01
      • 2014-10-10
      相关资源
      最近更新 更多