单线程

单线程

JavaScript的主要用途是与用户互动,以及操作DOM,这决定了它只能是单线程。

单线程就意味着,所有任务都需要排队,前一个任务结束,才会执行后一个任务。

比如 setTimeOut 规定在一定时间后才执行函数,如果时间很长,会使得网络闲置,JavaScript语言设计者意识到,这时主线程完全可以选择挂起这些处于等待中的任务,先运行排在后面的任务。等到setTimeOut返回了结果,再回过头,把挂起的任务继续执行下去。

同步任务 与 异步任务

  • 同步任务(synchronous)
    进入主线程中执行的任务
    指的是在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务,形成执行栈

  • 异步任务(asynchronous)
    进入任务队列中执行的任务
    指的是不进入主线程、而进入“任务队列”(task queue)的任务,只要异步任务有了运行结果,就在”任务队列”之中放置一个事件。

执行顺序:

执行完所有的同步任务 —> 再执行任务队列中的异步任务

事件与回调函数

任务队列是一个事件的队列,当异步任务有了运行结果,就会把对应的回调函数封装成一条消息放到“任务队列”,等待主线程的读取,遵循先进先出的原则。

回调函数,就是那些被主线程挂起的代码,异步任务必须指明回调函数,当主线程开始执行异步任务时,执行的就是对应的回调函数。

事件循环 Event Loop

主线程从任务队列里面取消息、执行消息,再取消息、再执行。消息队列为空时,就会等待直到消息队列变成非空。只有当前的消息执行结束,才会去取下一个消息。这种机制就叫做事件循环机制Event Loop,取一个消息并执行的过程叫做一次循环

定时器

定时器功能主要由setTimeout()和setInterval()这两个函数来完成,它们的内部运行机制完全一样,区别在于前者指定的代码是一次性执行,后者则为反复执行。以下主要讨论setTimeout()。

  • setTimeout(fun,time)

规定推迟 time 时间以后,才执行 fun 函数里的代码

console.log(1);
setTimeout(function(){console.log(2);},1000);
console.log(3);

// 输出是 1、3、2

    setTimeout(function(){console.log(1);}, 0);
    console.log(2);
// 输出是 2、 0 

以上可以看出即使 time 设置为0, setTimeout 的回调函数也只能等主线程中的执行栈清空,才会去执行任务队列里的代码

注意 在JavaScript中没有任何代码是立刻执行的,但一旦进程空闲就尽快执行。这意味着无论是setTimeout还是setInterval,所设置的时间都只是time毫秒被添加到队列中,而不是过n毫秒后立即执行。

process.nextTick和setImmediate

这是Node.js 提供的另外两个与”任务队列”有关的方法

  • process.nextTick把异步任务插入到任务队列的最前(”执行栈”的尾部,下一次Event Loop的头部)

  • setImmediate 把异步任务插入到任务队列的最后(当前”任务队列”的尾部添加事件)


总结
js 是单线程的,但是为了充分利用网络资源以及有一个良好的操作体验,任务又分为了同步任务和异步任务,js 总是先执行完同步任务,再去执行异步任务;同步任务会形成一个执行栈,当异步任务有了执行的结果后,它所对应的回调函数就会被放到任务队列中,等待被主线程执行。

思路:首先说 js 的作用是什么,引出单线程的概念,解释单线程,说明单线程的弊端,引出同步和异步任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值