对异步编程的理解

来源:互联网 发布:打电话的软件 编辑:程序博客网 时间:2024/05/01 21:52

因为很多人只是一味的强调javascript是单线程的,但单线程怎么能实现异步呢?就并没有讲清楚。其实所谓的单线程是指用户线程是单线程,而另外还有一个或多个线程处理异步代码的执行。

要理解javascript异步编程和其他语言同步编程的区别,可以从一个最简单的例子开始。在同步为主的语言中,如果需要等待10秒钟,通常是类似sleep 10之类的语句,在10秒之内整个进程挂起,也就是阻塞10秒。但javascript不是这样,它是使用setTimeout函数,从字面意思就已经可以看出区别了, 设一个timeout的时间, 在这段时间内cpu可以继续运行其他代码, 等10秒时间到了, 就用回调函数的形式来做应该10秒之后才做的事情。

接下来再说说阻塞的问题。很多文章里面在讲解的时候同步异步阻塞非阻塞混为一团,新手很难理解,最容易产生的误解就是同步=阻塞,异步=非阻塞。其实阻塞非阻塞跟同步异步没有任何关系。简单讲,阻塞就是一个api或者函数运行时间过长,而独占cpu导致其他代码不能运行,那么多长时间算阻塞呢?相信这只是一个相对的概念,只要明显影响到程序的性能和用户体验,就算阻塞吧。那跟同步异步是什么关系呢?阻塞的代码如果同步执行就会阻塞到自己后面代码的运行,所以自然而然的就想到异步来执行阻塞的代码,然而异步真能解决阻塞问题吗?下面继续讲。

node.js里面的异步
 
大家知道Javascript的基本语法跟其他编程语言大同小异,最大的不同就是把异步摆在首位,特别是node.js更是大部分api都是异步的,小量同步api。这与其他大部分语言刚好相反,也给习惯于同步编程思维的同学造成了很大的困扰,就是常说的转不过弯来,习惯性的认为代码是按顺序一行一行的往下执行。
 
上面介绍了异步非阻塞的概念,那么具体到node.js是怎么实现的呢?这里又会涉及到I/O的概念,具体不讲I/O的细节(操作系统原理都会讲),关键就一点,I/O操作通常比较耗时但不会独占CPU,典型的I/O比如文件读写,远程数据库读写,网络请求等。 先讲耗时,如果用同步API来进行I/O操作,在返回结果之前就只能等待,所以最好的办法上面已经讲过,就是进行异步操作。接着说一下不会霸占CPU的好处。在node.js进程里面,有一个用户线程(javascript所宣称的单线程)和一个异步线程池(用户无法直接访问), 如果跑在异步线程上的代码是阻塞的,那么这种异步根本就起不到消除阻塞的作用,为什么?原因就是阻塞代码会霸占cpu,导致本进程所有代码都等待不管是哪个线程。但是,,,刚刚讲的node.js里面的I/O API都是不会霸占CPU的,所以是非阻塞的,就不会出现这个问题。这就是node.js的最引以为傲的特性之一:异步非阻塞I/O.
 
上面只是强调异步非阻塞,那么对于真正的阻塞代码,node.js怎么办呢?不好意思。。。单个node.js进程真无能为力,跟同步编程语言相比没什么优势,只能用传统的方式,多进程,多开几个node.js进程,甚至多开几个服务器。任何语言都有它的强项和弱项,node.js的强项就是它本来的设计初衷:让开发者能够轻松的编写高性能的web服务器(进行的最多的就是网络和数据库的I/O操作),而不是做大量的CPU密集型的运算(不过我赶脚,就算要做很多阻塞操作,用多进程和多服务器又有何不可?node.js对此提供了足够的支持)。这样算是回答了上一小节最后的问题了吧:)

http://www.cnblogs.com/chrischjh/p/4667713.html

首先说一下javascript里面怎样书写异步函数。基本的方法就是,在你的函数定义里面调用别人已经提供的异步api (不管是原生的还是第三方的),你的函数也就是个异步函数了:

上面是一般异步函数的定义格式。setTimeout是javascript里面经常用的异步api。 做试验的时候经常用它来模拟异步操作,下面的例子模拟一个操作要运行1秒后才返回结果 (当然你可以设0秒,但仍然是异步的):

在node.js里面提供了其他的api来起到类似的作用(把你的同步代码写成异步函数),setImmediate或者process.nextTick,其作用就是异步调用你的代码。这两个基本上用法类似,但特定情况下是不同的,可以上网自行查找setImmediate,setTimeout(fn, 0)和process.nextTick 的区别,一般在不了解的情况下,建议使用setImmediate.

因为 settimeout 就是被设计成异步的啊,它为什么是异步的?

https://segmentfault.com/a/1190000004322358
http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html



0 0