单线程 JavaScript 的异步机制与经典 for 循环面试题

从一个经典的 for 循环问题开始

for (var i = 1; i <= 5; i++) {
  setTimeout( function timer() {
    console.log(i);
  }, i*1000)
}

输出是:每隔1秒,输出一个6,共5次。

原理

这样的输出,是由 JavaScript 的单线程及异步机制决定的。

JavaScript 是单线程的,所有的任务排队,按顺序一一执行。

异步执行可以实现多任务并发

相关必要概念引用
  • 并行: 同一时刻内多任务同时进行,多线程实现;
  • 并发,同一时间段内,多任务同时进行着,但是某一时刻,只有某一任务执行,单线程可实现;
  • 同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
  • 异步任务,不进入主线程、而进入”任务队列”(task queue)的任务,只有”任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
  • 堆(heap):内存中某一未被阻止的区域,通常存储对象(引用类型);
  • 栈(stack):后进先出的顺序存储数据结构,通常存储函数参数和基本类型值变量(按值访问);
  • 队列(queue):先进先出顺序存储数据结构。
  • 任务队列:一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,”任务队列”上第一位的事件就自动进入主线程。
    • 除了放置异步任务的事件,”任务队列”还可以放置定时事件,即指定某些代码在多少时间之后执行。这叫做”定时器”(timer)功能,也就是定时执行的代码。如果有定时器,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。
  • 回调函数(callback): 那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。
  • 事件循环: 主线程从”任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为事件循环(Event Loop)。

异步机制如图:

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值