通过延迟功能javascript阻止执行

问题描述

我正在使用以下代码来查看同步函数进入长循环时JavaScript执行是否被阻塞。

function delayBySeconds(sec){
  let start = now = Date.now();
  while((now - start) < (sec * 1000)){
    //console.log(now);
    now = Date.now();
  }
}

const seconds = 20;
delayBySeconds(seconds);
console.log(`${seconds} seconds passed`);

它立即打印消息,表明执行不等待被调用函数完成其循环。这是如何运作的?我的意思是,如果delayBySeconds函数正常工作,如何立即打印消息?当然,这只是实验性的,在实际延迟中使用它是没有意义的。

解决方法

这是同步代码执行。控制台正在等待,直到功能未完全执行。您没有看到任何延迟,因为您没有在循环内执行任何任务。

如果您在while循环中取消注释控制台,则会看到延迟。

,

由于JavaScript始终是同步的并且是单线程的,因此它不会等待函数执行完成才继续执行下一条语句。因此,为了适当地等待函数完成执行,我们使用Promise / Then排序的“框架”对函数进行异步调用,即在继续操作之前等待其完成。现在,在ES2017之后,我们可以使用async / await来简化该过程。

使用Promise的代码段

const delayBySeconds = sec => new Promise(resolve => {
  let start = now = Date.now();
  while((now - start) < (sec * 1000)){
    // console.log(now - start);
    now = Date.now();
  }
  resolve()
})

const seconds = 10;
delayBySeconds(seconds).then(()=>
console.log(`${seconds} seconds passed`))

使用异步/等待的代码段

const delayBySeconds = async sec => {
  let start = now = Date.now();
  while((now - start) < (sec * 1000)){
    // console.log(now - start);
    now = Date.now();
  }
  return
}

const main = async () => {
  const seconds = 7;
  await delayBySeconds(seconds)
  console.log(`${seconds} seconds passed`)
}

main()

请注意,异步/等待只能在异步函数中使用,因此如果您使用本地js,则必须将其包装在函数中。但是,有些工具(例如Deno)是一个相当新的后端js框架,它对async / await具有全局支持,因此您不必将其包装在那里。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...