很多开发者都说JavaScript是单线程的,但是单线程是如何实现异步的呢?然而并没有详细说过,其实JavaScript还有一条或者多条线程用来实现异步操作,也就是异步队列。
举个例子:
马路上有很多车,一辆接一辆的排着跑,突然排在最前面的车坏了,
这时候你是让后面的所有的车都等它修好在一起跑吗?
然而是不可能的,那样交通就乱掉了。
这时候就出现了应急车道,把坏的车挪到应急车道上去,
后面的车继续跑,等坏的车修好了,在挪到车道上去正常跑。
这就是JavaScript中的异步执行队列。
什么是同步什么是异步呢?
同步
简而言之,同步就是从上往下依次执行,就像java,c,python等强类型的语言。都是顺时同步执行,很少有异步操作。
而同步就要求开发者的编码要严谨,如果有疏忽,就会导致运行出错,运行卡顿,导致用户体验差等,
举个简单的例子说明什么是同步执行
这就是同步执行, f1() 在f2()的上面所以先执行 f1() 在执行f2() 简单说就是一个先进先出的队列。后者必须等待前者的结果出来才会运行
那么如果我不想让f2等着f1执行完在执行,我就想让他正常执行呢? 那你就用异步函数编程就行 我推荐大家看一下阮一峰老师的异步函数式编程(http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html
),当然面试的时候不推荐拿出来吹牛逼。
异步
那么就把f2当成f1的参数,把f2写成f1的回调函数,这样f2不用再等待f1是否执行完成,只要过了1s就会执行f2函数
function f1 (callback) {
setTimeOut (() => {
callBack()
}, 1000)
}
f1(f2)
阻塞
什么是阻塞?
阻塞与非阻塞其实跟同步与异步并没有什么直接关系。要正确理解。不要说阻塞=同步,非阻塞=异步
最常见的阻塞现象,例如 死循环, 用户体验差, 运行卡顿等。引起阻塞的原因,就是一个api或者函数运行时,独占cpu导致其他代码无法运行。
为什么大家会把阻塞与同步联系在一起了?
开发者都知道同步代码从上至下依次运行,当运行遭遇阻塞,后面的代码自然而然不会运行。
非阻塞呢?
一说到非阻塞大家应该会想到 node, 因为nodejs最大的优点就是他的 异步非阻塞IO,node中大部分都是异步的,包括基于node开发的express,koa等框架。
node进程中,一个用户线程(js单线程),一个异步线程池(用户无法直接访问到),对于真正的阻塞代码,比如异步中发生阻塞,如果跑在异步中的仍然是阻塞代码,那么这种异步根本起步到解决阻塞的作用,因为阻塞代码会独占cpu,多以导致本进程上面的所有代码都要等待,不管是哪个线程,但是node的IO是不会霸占cpu的,所以node最出色的就是他的异步非阻塞IO。真正碰到阻塞代码,node也只能开多线程多服务来解决了,因为每一门语言必然有他的优点与缺点,node本身就是为了让开发者更好的开发web后台服务的。
同步异步,阻塞与非阻塞就说到这里了。