javascript 同步异步的理解总结
Java是多线程语言,利用多线程可以处理很多事情,文件上传,下载
JavaScript 是单线程 同一时间内每次只能执行一个任务,如果同一时间有多个任务,就需要等待上一任务执行结束后才能执行下一任务。
fun f1(){
console.log(1)
}
fun f2(){
console.log(2)
}
f1()
f2()
//1
//2
js代码都是自上而下执行,执行完f1() 然后再执行f2() 这是同步执行,如果f1是读取文件或者ajax操作,读取文件,ajax会比较耗时,我们不能等f1执行完才执行f2,解决这种问题 就产生了 同步/异步的概念
为什么设计JavaScript为单线程语言
如果javascript为多线程,同一时间内两个线程对同一dom 进行了操作,一个新增,一个删除,会引起复杂的同步计算问题,避免产生这种问题设计JavaScript为单线程
同步任务异步任务的概念
单线程的JavaScript,同步任务在主线程上顺序排队执行任务,ajax操作,settimeout这类的异步任务可以挂起不在主线程,但还是在任务队列排列,等待数据回调成功后再放回主线程继续执行相当于插队执行,但线程仍然只有一个线程。
同步任务:主线程排队执行的任务,前一个执行完毕后面一个继续执行,浏览器网页渲染,元素渲染是同步任务
异步任务:不进入主线程,进入在任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程,当打开网站时,像图片的加载,音乐的加载,就是一个异步任务
function fun1(){
console.log(1)
}
function fun2(){
console.log(2)
}
function fun3(){
console.log(3)
}
fun1()
setTimout(()=>{
fun2()
},0)
fun3()
//1
//3
//2
主线程执行fun1() fun3() fun2是异步编程挂起在任务队列里,fun2异步回调结束放回主线程继续执行任务。
异步机制实现原理
异步实现主要是函数回调和事件循环
异步任务不进入主线程,是进入了任务队列,任务队列是一个先进先出的数据结构,ajax请求是一个异步任务,该任务不阻塞进程不进入主线程而是先进入任务队列,等IO完成后,会在任务队列中添加一个事件,表示异步任务完成,可以进入主线程
主线程有可能在执行别的任务,当主线程没有任务操作的时候 会读取任务队列的事件,排在前面的事件优先处理,如果该任务指定了回调函数,主线程在处理该事件时候会执行指定回调函数代码,就是执行了异步任务
单线程是循环读取任务队列的,主线程没有任务时候读会任务队列是否有新任务,循环读取到有新的任务,每个任务都是由事件触发也叫事件循环
同步任务都在主线程执行,是一个执行栈
主线程之外任务队列存放异步任务,异步任务有了结果,会在任务队列中放置一个事件
主线程执行栈任务执行完毕会循环读取任务队列,读取到任务事件,对应的异步任务便结束等待状态,进入主线程执行栈开始执行
主线程循环上面三步