5-1 理解异步
本节编程练习不计算学习进度,请电脑登录imooc.com操作

理解异步

JavaScript编程几乎总是伴随着异步操作,传统的异步操作会在操作完成之后,使用回调函数传回结果,而回调函数中则包含了后续的工作。这也是造成异步编程困难的主要原因:

我们一直习惯于“线性”地编写代码逻辑,但是大量异步操作所带来的回调函数,会把我们的算法分解地支离破碎。

此时我们不能用if来实现逻辑分支,也不能用while/for/do来实现循环,更不用说异步操作之间的组合、错误处理以及取消操作了。因此也就诞生了如jQuery Deferred这样的辅助类库。

我们常见的异步操作:

定时器setTimeout
postmessage
WebWorkor
CSS3 动画
XMLHttpRequest
HTML5的本地数据
等等…

JavaScript要求在与服务器进行交互时要用异步通信,如同AJAX一样。因为是异步模型,所以在调用Transaction游览器提供的本地数据接口时候类似AJAX(这里我是假设),浏览器自己有内部的XHR方法异步处理,但是此时的JS代码还是会同步往下执行,其实就是无阻塞的代码。

问题:因为无阻塞,代码在发送AJAX这个请求后会继续执行,那么后续的操作如果依赖这个数据的就会出错了,所以这里就需要等待AJAX返回,才能执行后续操作。

因为异步而导致流程不正确,或者说我们的应用在某个程度上依赖第三方API的数据,那么就会面临一个共同的问题:

我们无法获悉一个API响应的延迟时间,应用程序的其他部分可能会被阻塞,直到它返回结果。Deferreds 的引入对这个问题提供了一个更好的解决方案,它是非阻塞的,并且与代码完全解耦。

当然异步操作也可以提供一个类似于成功回调,失败回调的通知接口。

JS是单线程语言,就简单性而言,把每一件事情(包括GUI事件和渲染)都放在一个线程里来处理是一个很好的程序模型,因为这样就无需再考虑线程同步这些复杂问题。

另一方面,他也暴露了应用开发中的一个严重问题,单线程环境看起来对用户请求响应迅速,但是当线程忙于处理其它事情时,就不能对用户的鼠标点击和键盘操作做出响应。

任务

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <script src="http://code.jquery.com/jquery-latest.js"></script>
  6. <title></title>
  7. </head>
  8. <body>
  9.  
  10. <button id="go">&raquo; Run</button>
  11. <div id="block">慕课网,你好!</div>
  12.  
  13. <script type="text/javascript">
  14.  
  15. //定时器改变流程
  16. show(1)
  17. setTimeout(function() {
  18. show(2)
  19. }, 0)
  20. show(3)
  21.  
  22.  
  23. //执行异步动画
  24. //因为代码的执行是按照从上至下
  25. //但是由于加入了动画,动画形成了异步,所以实际的改变值必须等动画完成才能得到
  26. //但是同步逻辑3其实已经运行,所以3要等待2结束才可以
  27. $("#go").click(function() {
  28. var block = $("#block");
  29. show('1.动画流程代码开始,对象长度'+ block.css('width'))
  30. block.animate({
  31. width : "70%",
  32. opacity : 0.4,
  33. marginLeft : "0.6in",
  34. fontSize : "3em",
  35. borderWidth : "10px",
  36. }, 1000, function() {
  37. show('2.动画执行结束束,对象长度'+ block.css('width'))
  38. });
  39. show('3.动画流程代码结束,对象长度'+ block.css('width'))
  40. });
  41.  
  42.  
  43. function show(data) {
  44. $("body").append('<li>' + data + '</li>')
  45. }
  46.  
  47. </script>
  48.  
  49. </body>
  50. </html>
下一节