JS中同步与异步

一、单线程语言

首先,我们了解到JS是一个单线程的语言,也就是说,在JS中我们是无法同时进行两个任务的,,所以在js中所谓的异步任务也并不是实现多个任务并行执行,而是合理的进行任务挂起,多个任务时,只可以进行当前的一个任务,其他任务就会进入任务队列进行等待,js的单线程其实也是取决的JS是一个脚本语言,主要用来实现与用户的交互,利用JavaScript,我们可以实现对DOM的各种各样的操作,如果JavaScript是多线程的话,一个线程在一个DOM节点中增加内容,另一个线程要删除这个DOM节点,那么这个DOM节点究竟是要增加内容还是删除呢?这会带来很复杂的同步问题,因此,JavaScript是单线程的。

二、同步和异步任务

1、同步和异步的必要性

在单线程中的同步和异步是如何实现的呢?在单线程中,我们在同一时间内只能处理一个任务,所以其他的任务则在任务列中进行排队,前一个任务执行完才能进行下一个任务,这样就会出现,当我们执行一个需要大量时间来完成的任务时,后面的任务就必须等待,例如ajax像后台获取数据是,不得不等到所欲数据获取完毕才能进行下一步,用户等待时间过长,很降低用户体验,因此,JS中就考虑到将某个任务挂起,先运行排在后面的任务,等回过头再来执行挂起的任务,合理安排任务挂起可以在保证任务执行的同时减少不必要的等待时间。

2、同步任务

是指在当前任务列中执行的任务,也就是主线程的任务,按照顺序执行,只有前一个执行完才能执行下一个,举个栗子

`console.log("aaa");`

​    `for(var i=0;i<3;i++){`

​	`console.log("ccc");`

​    `}`

​    `console.log("bbb");`

输出:aaa ccc ccc ccc bbb,

可以看出输出会依次输出,因为代码是从上向下运行的,执行完aaa的输出才会进入循环。这就是同步在一个任务列中的任务,按照顺序,遇到需要时间运行才能结束的代码时,必须等待,等待结束带能执行下一个任务。

3、异步任务

异步就是不进入主线程,而是进入后面任务队列,只有当前任务队列执行到后面时,这个被挂起的任务才能被执行,才会进入主线程。例如网页中图片的加载,就是一个异步任务,在js我们会认识到几个常见的异步操作,例如setTimeout,promise,async/await,setInterval等,举个栗子来看看异步操作

function` `f1() {
 ``console.log(1);
}
function` `f2() {
 ``console.log(2);
}
function` `f3() {
 ``console.log(3);
}
f1();
setTimeout(``function``(){
 ``f2();
},0);
f3();

输出:1 3 2

4、异步的运行机制

具体来说,异步执行的运行机制如下。(同步执行也是如此,因为它可以被视为没有异步任务的异步执行。)

(1)所有步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

“任务队列"是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列”,就是读取里面有哪些事件。

“任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列”,等待主线程读取。

所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。

"任务队列"是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,"任务队列"上第一位的事件就自动进入主线程。但是,由于存在后文提到的"定时器"功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值