JavaScript的单线程和setTimeout的异步

引言

JavaScript 是单线程的,那么类似 setTimeout 的异步如何实现呢?

背景知识

setTimeout(fn, millisec)

millisec 毫秒后执行 fn 函数

注意:对于 setTimeout(fn, 0)的情况

例:

// 输出 2 3 1,而非 1 2 3
setTimeout(function () {
  console.log(1);
}, 0);
console.log(2);
console.log(3);

虽然 setTimeout(fn, 0)的意思是 0ms 后执行 fn,也就是立刻执行
但是这个“立刻”指的是主程序执行完后的“立刻”
不仅 0 如此,所有的延迟执行 setTimeout 都是如此
如果有一堆这样的函数,它们会被放入等待队列中

解释

Js 单线程,但是浏览器内核是多线程的
一个浏览器至少有三个常驻线程:

  1. JavaScript 引擎线程
  2. GUI 渲染线程
  3. 浏览器事件触发线程

除此之外还有:

  1. 定时器线程,专门处理 setInterval 和 setTimeOut
  2. 异步 HTTP 请求线程

其中,JS 引擎线程是主线程

当遇到 setTimeout 函数,JS 引擎线程则将其交给定时器线程去执行,自己则执行下面的代码

定时器线程计时结束后,会将回调函数放入任务队列(不是立即执行!)

主线程处理完了自己的任务后,才会去执行任务队列里的任务

虽然都在任务队列中,也有宏任务与微任务之分

宏任务和微任务

  • 宏任务
    1. 定时器 setTimeout setInterval
  • 微任务
    1. Promise .then/catch/finally 的执行
  1. 执行同步代码
  2. 清空微任务队列
  3. 执行宏任务.如果这期间遇到宏任务/微任务,塞进对应的层级里即可

注:Promise 里面执行的逻辑直接执行就好,可认为是同步任务。只有.then/catch/finally 才是微任务

function app() {
  setTimeout(() => {
    console.log('1-1');
    Promise.resolve().then(() => {
      console.log('2-1');
    });
  });
  console.log('1-2');
  Promise.resolve().then(() => {
    console.log('1-3');
    setTimeout(() => {
      console.log('3-1');
    });
  });
}
app();

运行结果

1-2
1-3
1-1
2-1
3-1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iAhsqjUq-1655706527186)(https://segmentfault.com/img/remote/1460000039055445)]

参考:
https://segmentfault.com/a/1190000039055443

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值