JavaScript同步一定比异步先执行吗

新手上路,请多包涵

JavaScript同步一定比异步先执行吗

//做一个时间戳
var time = new Date().getTime()
setTimeout(()=>{
    console.log("我延迟3秒后显示");
    console.log(`我实际的延迟时间:${new Date().getTime() - time}`)
},3000)
while(new Date().getTime() - time < 6000){}
console.log("我6秒后的显示")

//我6秒后的显示
//我延迟3秒后显示
//我实际的延迟时间:6002

由上面的例子,我是不是可以得出这样一个结论:同步比异步先执行,必须要同步都执行完成后,才能执行异步函数

setTimeout(()=>{
    console.log("我只延迟了一秒")
},1000)
setTimeout(()=>{
    while(true){}
},2000)
setTimeout(()=>{
    console.log("我只延迟了五秒")
},3000)
console.log("我不是setTimeout函数")

//我不是setTimeout函数
//我只延迟了一秒

上面的例子中,由于while(true){}死循环的关系,导致浏览器假死,不打印出:我只延迟了五秒,是否平时理解的异步函数之间互不影响是错误的
望大牛解答,谢谢各位了

阅读 3k
3 个回答

建议题主去阅读事件循环相关技术文档,我这里简单解释一下:

  1. js事件循环有两个队列:宏任务、微任务,timeout属于宏任务
  2. 宏任务队列是按顺序出队列,然后执行。
  3. 你上面代码中,while循环那个timeout是先入队列的,所以先出队列,被执行
  4. 执行过程中碰到死循环,然后这个宏任务不能结束
  5. 所以延迟5秒那个宏任务不能被执行

你可以试试这个:

const start = Date.now()

setTimeout(()=>{
  console.log("我只延迟了一秒")
},1000)
setTimeout(()=>{
  while(Date.now() - start < 6000){}
  console.log("我延迟了八秒")
},2000)
setTimeout(()=>{
  console.log("我只延迟了五秒")
},3000)
console.log("我不是setTimeout函数")

你这不是异步函数互不影响的问题,你异步函数把主线程阻塞了。是这个问题

关于同步/异步执行问题,关键知识点:Event Loop
推荐阅读:从多线程到Event Loop全面梳理


了解之后,只要不涉及到DOM的操作问题,一定是同步优先,因为同步可以看做一个“宏任务”,一切异步都可以归类为“微任务”或“另一个宏任务”。
如果涉及到DOM操作,或者说,JS阻塞与同步DOM执行渲染的关系时,
推荐阅读:JS中操作DOM是"同步"还是"异步"?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏