Javascript异步编程详解异步编程详解
Javascript异步编程详解
Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)."异步模式"非常重要。在浏览器
端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一
的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。
前言
你可能知道,Javascript语言的执行环境是"单线程"(single thread)。
所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以
此类推。
这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会
拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页
面卡在这个地方,其他任务无法执行。
为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous).
"异步模式"非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服
务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下
降,很快就会失去响应。
setTimeout 函数的弊端
延时处理当然少不了 setTimeout这个神器,很多人对 setTimeout函数的理解就是:延时为 n 的话,函数会在 n 毫秒之后执
行。事实上并非如此,这里存在三个问题:
一个是 setTimeout函数的及时性问题, setTimeout是存在一定时间间隔的,并不是设定 n 毫秒执行,他就是 n 毫秒执行,可能
会有一点时间的延迟,setInterval 和 setTimeout 函数运转的最短周期是 5ms 左右,这个数值在 HTML规范 中也是有提到的:
Let timeout be the second method argument, or zero if the argument was omitted.如果 timeout 参数没有写,默认为 0
If nesting level is greater than 5, and timeout is less than 4, then increase timeout to 如果嵌套的层次大于 5 ,并且 timeout
设置的数值小于 4 则直接取 4.
其次是while循环会阻塞setTimeout的执行
看这段代码:
结果是死循环导致setTimeout不执行,也导致alert不执行
js是单线程,所以会先执行while(t){}再alert,但这个循环体是死循环,所以永远不会执行alert。
至于说为什么不执行setTimeout,是因为js的工作机制是:当线程中没有执行任何同步代码的前提下才会执行异步代
码,setTimeout是异步代码,所以setTimeout只能等js空闲才会执行,但死循环是永远不会空闲的,所以setTimeout也永远不
会执行。
第三是,try..catch捕捉不到他的错误
异步编程方法
回调函数
这是异步编程最基本的方法。