[?]|登录|免费注册®
高级...

浏览选项

  • 手机网站排名
  • 手机网用户圈
  • UA设置:(默认)
  • 设置浏览参数
  • 重新下载页面

[+](无标题)

?博客园_首页代码改变世界uuid:ee2065bb-5315-4eb8-bed1-19187874c546;id=48962014-07-26T04:55:10Zfeed.cnblogs.comhttp://www.cnblogs.com/wujiaoniu/p/3869893.html无角牛MVC通用后台 - 无角牛每个人都在忙碌中度过一天又一天。或者是工作中的,或者是生活中的。也许是快乐的,也可能是繁琐的。但总会或多或少的从网络中学习知识,丰富自己。学习了很高兴,奉献了也很快乐。 一直以来我都想能够总结出一套方便管理的权限管理方案。幸好近期时间充裕,打算写些开源的东西出来,算做进期的一个总结,也供朋友们...2014-07-26T04:32:00Z2014-07-26T04:32:00Z无角牛http://www.cnblogs.com/wujiaoniu/<p>  每个人都在忙碌中度过一天又一天。或者是工作中的,或者是生活中的。也许是快乐的,也可能是繁琐的。<br /><br />但总会或多或少的从网络中学习知识,丰富自己。学习了很高兴,奉献了也很快乐。<br /><br />  一直以来我都想能够总结出一套方便管理的权限管理方案。幸好近期时间充裕,打算写<br /><br />些开源的东西出来,算做进期的一个总结,也供朋友们共同探讨共同完善进步吧。名字就<br /><br />订为&ldquo;无角牛MVC通用后台&rdquo;,之所以叫MVC,就是因为是用MVC3.0写的,其实对WebForm也是适用的。<br /><br />目录如下:<br /><br />第一篇:无角牛MVC通用后台数据库设计<br /><br />第二篇:无角牛MVC通用后台菜单管理<br /><br />第三篇:无角牛MVC通用后台权限角色分配<br /><br />第四篇:无角牛MVC通用后台权限用户分配<br /><br />第五篇:无角牛MVC通用后台缓存<br /><br />第六篇:无角牛MVC通用后台批量导入方案<br /><br />第七篇:无角牛MVC通用后台导出<br /><br />第八篇:无角牛MVC通用后台一些注意事项<br /><br />第九篇:无角牛MVC通用后台源码1.0放送<br /><br />放一张展现图:</p><p><img src="http://images.cnitblog.com/i/646132/201407/261240339799174.png" alt="" /></p><img src="http://counter.cnblogs.com/blog/rss/3869893" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/wujiaoniu/p/3869893.html" target="_blank">无角牛MVC通用后台</a>,转载请注明。</p>http://www.cnblogs.com/zjflove/p/3869864.html炎炎夏日,走入美妙的前端设计案例 - zhangjf_兔子1、 嘎嘎夏天到了!最近同事分享我一个案例,说这效果不错,看看我能不能实现 ( 鄙人后台程序员,热爱前端,前端是女人的外貌; 后台是女人的内涵) 我们先从外貌说起,看原始案例的效果 外貌看起来 很简洁,主题很明确,效果也很流畅,还算比较炫吧,我一下就喜欢她了!刚开始我以为她的内涵可能是css3...2014-07-26T04:06:00Z2014-07-26T04:06:00Zzhangjf_兔子http://www.cnblogs.com/zjflove/<p><span style="font-family: 幼圆;">1、 &nbsp;嘎嘎夏天到了!最近同事分享我一个案例,说这效果不错,看看我能不能实现</span></p><p><span style="font-family: 幼圆;">&nbsp; &nbsp;( 鄙人后台程序员,热爱前端,前端是女人的外貌; 后台是女人的内涵)</span></p><p><span style="color: #888888;">&nbsp; </span><span style="font-family: 幼圆;"><strong>我们先从外貌说起,看原始案例的效果</strong></span></p><p><strong>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<img src="http://images.cnitblog.com/i/149713/201407/261150163221220.gif" alt="" /></strong></p><p>&nbsp;</p><p>&nbsp; <span style="font-family: 幼圆;"><strong>外貌看起来 很简洁,主题很明确,效果也很流畅,还算比较炫吧,我一下就喜欢她了!</strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp;刚开始我以为她的内涵可能是css3居多,其实不然是css居多</strong></span></p><p><span style="font-family: 幼圆;"><strong>/-----------------------------------骚骚的分割线---------------------------------------/</strong></span></p><p><span style="font-family: 幼圆;">2、我的实现</span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp;--布局:5个对象绝对定位、改变每个对象的left和top值,对象有大有小(用css3 缩放来对图片进行缩放),</strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;而且每个图片的间距有对称,分析图如下:</strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp;<img src="http://images.cnitblog.com/i/149713/201407/261159494634522.jpg" alt="" /></strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp; &nbsp;</strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; 具体代码如下:</strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp; &nbsp;</strong></span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">style </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text/css"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;"> 2</span> <span style="background-color: #f5f5f5; color: #800000;"> *<br/></span><span style="color: #008080;"> 3</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;"> 4</span> <span style="background-color: #f5f5f5; color: #ff0000;"> margin</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 0</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;"> 5</span> <span style="background-color: #f5f5f5; color: #ff0000;"> padding</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 0</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;"> 6</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;"> 7</span> <span style="background-color: #f5f5f5; color: #800000;"> #wrap<br/></span><span style="color: #008080;"> 8</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;"> 9</span> <span style="background-color: #f5f5f5; color: #ff0000;"> border</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 1px solid red</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">10</span> <span style="background-color: #f5f5f5; color: #ff0000;"> position</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> relative</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">11</span> <span style="background-color: #f5f5f5; color: #ff0000;"> width</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 90%</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">12</span> <span style="background-color: #f5f5f5; color: #ff0000;"> padding</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 5%</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">13</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;">14</span> <br/><span style="color: #008080;">15</span> <span style="background-color: #f5f5f5; color: #800000;"> #list<br/></span><span style="color: #008080;">16</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;">17</span> <span style="background-color: #f5f5f5; color: #ff0000;"> list-style</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> none</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">18</span> <span style="background-color: #f5f5f5; color: #ff0000;"> position</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> absolute</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">19</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;">20</span> <span style="background-color: #f5f5f5; color: #800000;"> #list li<br/></span><span style="color: #008080;">21</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;">22</span> <span style="background-color: #f5f5f5; color: #008000;">/*</span><br/><span style="color: #008080;">23</span> <span style="background-color: #f5f5f5; color: #008000;"> -webkit-transition: all 0.6s ease;</span><span style="background-color: #f5f5f5; color: #008000;">*/</span><br/><span style="color: #008080;">24</span> <span style="background-color: #f5f5f5; color: #ff0000;"> position</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> absolute</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">25</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;">26</span> <br/><span style="color: #008080;">27</span> <span style="background-color: #f5f5f5; color: #800000;"> #list li:nth-of-type(5)<br/></span><span style="color: #008080;">28</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;">29</span> <span style="background-color: #f5f5f5; color: #ff0000;"> -webkit-transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(1)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">30</span> <span style="background-color: #f5f5f5; color: #ff0000;"> transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(1)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">31</span> <span style="background-color: #f5f5f5; color: #ff0000;"> left</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 120px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">32</span> <span style="background-color: #f5f5f5; color: #ff0000;"> top</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 100px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">33</span> <span style="background-color: #f5f5f5; color: #ff0000;"> z-index</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 5</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">34</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;">35</span> <span style="background-color: #f5f5f5; color: #008000;">/*</span><span style="background-color: #f5f5f5; color: #008000;">-----1、3----</span><span style="background-color: #f5f5f5; color: #008000;">*/</span><br/><span style="color: #008080;">36</span> <span style="background-color: #f5f5f5; color: #800000;"> #list li:nth-of-type(1)<br/></span><span style="color: #008080;">37</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;">38</span> <span style="background-color: #f5f5f5; color: #ff0000;"> -webkit-transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(0.8)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">39</span> <span style="background-color: #f5f5f5; color: #ff0000;"> transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(0.8)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">40</span> <span style="background-color: #f5f5f5; color: #ff0000;"> left</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 30px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">41</span> <span style="background-color: #f5f5f5; color: #ff0000;"> top</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 80px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">42</span> <span style="background-color: #f5f5f5; color: #ff0000;"> z-index</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 4</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">43</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;">44</span> <span style="background-color: #f5f5f5; color: #800000;"> #list li:nth-of-type(4)<br/></span><span style="color: #008080;">45</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;">46</span> <span style="background-color: #f5f5f5; color: #ff0000;"> -webkit-transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(0.8)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">47</span> <span style="background-color: #f5f5f5; color: #ff0000;"> transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(0.8)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">48</span> <span style="background-color: #f5f5f5; color: #ff0000;"> left</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 210px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">49</span> <span style="background-color: #f5f5f5; color: #ff0000;"> top</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 70px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">50</span> <span style="background-color: #f5f5f5; color: #ff0000;"> z-index</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 3</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">51</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;">52</span> <span style="background-color: #f5f5f5; color: #008000;">/*</span><span style="background-color: #f5f5f5; color: #008000;">----4、5----</span><span style="background-color: #f5f5f5; color: #008000;">*/</span><br/><span style="color: #008080;">53</span> <span style="background-color: #f5f5f5; color: #800000;"> #list li:nth-of-type(2)<br/></span><span style="color: #008080;">54</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;">55</span> <span style="background-color: #f5f5f5; color: #ff0000;"> -webkit-transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(0.65)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">56</span> <span style="background-color: #f5f5f5; color: #ff0000;"> transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(0.65)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">57</span> <span style="background-color: #f5f5f5; color: #ff0000;"> left</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 80px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">58</span> <span style="background-color: #f5f5f5; color: #ff0000;"> top</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 40px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">59</span> <span style="background-color: #f5f5f5; color: #ff0000;"> z-index</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 2</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">60</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;">61</span> <span style="background-color: #f5f5f5; color: #800000;"> #list li:nth-of-type(3)<br/></span><span style="color: #008080;">62</span> <span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;">63</span> <span style="background-color: #f5f5f5; color: #ff0000;"> -webkit-transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(0.65)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">64</span> <span style="background-color: #f5f5f5; color: #ff0000;"> transform</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> scale(0.65)</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">65</span> <span style="background-color: #f5f5f5; color: #ff0000;"> left</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 160px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">66</span> <span style="background-color: #f5f5f5; color: #ff0000;"> top</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 40px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">67</span> <span style="background-color: #f5f5f5; color: #ff0000;"> z-index</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;"> 1</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;">68</span> <span style="background-color: #f5f5f5; color: #000000;">}</span><br/><span style="color: #008080;">69</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">style</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">70</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">71</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">body </span><span style="color: #ff0000;">style</span><span style="color: #0000ff;">="background: #abcdef;"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">72</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="prev"</span><span style="color: #ff0000;"> style</span><span style="color: #0000ff;">="background: #abcdef; width: 20px; height: 20px; border: 1px solid red;<br/></span><span style="color: #008080;">73</span> <span style="color: #0000ff;"> position: absolute; left: 100px; top: 250px; cursor: pointer;"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">74</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">&lt;<br/></span><span style="color: #008080;">75</span> <span style="color: #800000;"> &lt;/div</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">76</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="next"</span><span style="color: #ff0000;"> style</span><span style="color: #0000ff;">="background: #abcdef; width: 20px; height: 20px; border: 1px solid red;<br/></span><span style="color: #008080;">77</span> <span style="color: #0000ff;"> position: absolute; left: 200px; top: 250px; cursor: pointer;"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">78</span> <span style="color: #000000;"> &gt;&gt;<br/></span><span style="color: #008080;">79</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">80</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="wrap"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">81</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ul </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="list"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">82</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">83</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="hzp/pro1.png"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">84</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">85</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="hzp/pro2.png"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">86</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">87</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="hzp/pro3.png"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">88</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">89</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="hzp/pro4.png"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">90</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">91</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="hzp/pro5.png"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">92</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ul</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">93</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">94</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span></div><p>&nbsp;</p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp;--js实现动态效果,先来看一张我的分析图</strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp;&nbsp;<img src="http://images.cnitblog.com/i/149713/201407/261159085417324.jpg" alt="" /></strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp;</strong></span></p><p><span style="font-family: 幼圆;"><strong>&nbsp; &nbsp; 完整的js代码:</strong></span></p><p>&nbsp;---------------------------------------------------</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text/javascript"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;"> 2</span> <br/><span style="color: #008080;"> 3</span> <span style="background-color: #f5f5f5; color: #000000;"> window.onload </span><span style="background-color: #f5f5f5; color: #000000;">=</span> <span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> () {<br/></span><span style="color: #008080;"> 4</span> <br/><span style="color: #008080;"> 5</span> <br/><span style="color: #008080;"> 6</span> <span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> list </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> document.getElementById(</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">list</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">);<br/></span><span style="color: #008080;"> 7</span> <span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> aLis </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> list.getElementsByTagName(</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">li</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">);<br/></span><span style="color: #008080;"> 8</span> <span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> arr </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> [];<br/></span><span style="color: #008080;"> 9</span> <br/><span style="color: #008080;">10</span> <span style="background-color: #f5f5f5; color: #000000;"> $(</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">li</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">).each(</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> (k, v) {<br/></span><span style="color: #008080;">11</span> <span style="background-color: #f5f5f5; color: #000000;"> arr[k] </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> { left: getStyle(</span><span style="background-color: #f5f5f5; color: #0000ff;">this</span><span style="background-color: #f5f5f5; color: #000000;">, </span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">left</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">), top: getStyle(</span><span style="background-color: #f5f5f5; color: #0000ff;">this</span><span style="background-color: #f5f5f5; color: #000000;">, </span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">top</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">), scale: getStyle(</span><span style="background-color: #f5f5f5; color: #0000ff;">this</span><span style="background-color: #f5f5f5; color: #000000;">, </span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">-webkit-transform</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">), zIndex: getStyle(</span><span style="background-color: #f5f5f5; color: #0000ff;">this</span><span style="background-color: #f5f5f5; color: #000000;">, </span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">z-index</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">) };<br/></span><span style="color: #008080;">12</span> <span style="background-color: #f5f5f5; color: #000000;"> });<br/></span><span style="color: #008080;">13</span> <br/><span style="color: #008080;">14</span> <span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> getStyle(obj, attr) {<br/></span><span style="color: #008080;">15</span> <span style="background-color: #f5f5f5; color: #0000ff;">if</span><span style="background-color: #f5f5f5; color: #000000;"> (obj.currentStyle) {<br/></span><span style="color: #008080;">16</span> <span style="background-color: #f5f5f5; color: #0000ff;">return</span><span style="background-color: #f5f5f5; color: #000000;"> obj.currentStyle[attr];<br/></span><span style="color: #008080;">17</span> <span style="background-color: #f5f5f5; color: #000000;"> }<br/></span><span style="color: #008080;">18</span> <span style="background-color: #f5f5f5; color: #0000ff;">return</span><span style="background-color: #f5f5f5; color: #000000;"> getComputedStyle(obj)[attr];<br/></span><span style="color: #008080;">19</span> <span style="background-color: #f5f5f5; color: #000000;"> }<br/></span><span style="color: #008080;">20</span> <br/><span style="color: #008080;">21</span> <span style="background-color: #f5f5f5; color: #000000;"> $(</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">#prev</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">).click(</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> () {<br/></span><span style="color: #008080;">22</span> <span style="background-color: #f5f5f5; color: #000000;"> arr.push(arr.shift()); </span><span style="background-color: #f5f5f5; color: #008000;">//</span><span style="background-color: #f5f5f5; color: #008000;">prev</span><br/><span style="color: #008080;">23</span> <span style="background-color: #f5f5f5; color: #008000;">//</span><span style="background-color: #f5f5f5; color: #008000;">左边 </span><br/><span style="color: #008080;">24</span> <span style="background-color: #f5f5f5; color: #000000;"> toExchage();<br/></span><span style="color: #008080;">25</span> <br/><span style="color: #008080;">26</span> <span style="background-color: #f5f5f5; color: #000000;"> })<br/></span><span style="color: #008080;">27</span> <br/><span style="color: #008080;">28</span> <span style="background-color: #f5f5f5; color: #000000;"> $(</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">#next</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">).click(</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> () { <br/></span><span style="color: #008080;">29</span> <span style="background-color: #f5f5f5; color: #000000;"> arr.unshift(arr.pop()); </span><span style="background-color: #f5f5f5; color: #008000;">//</span><span style="background-color: #f5f5f5; color: #008000;">next</span><br/><span style="color: #008080;">30</span> <span style="background-color: #f5f5f5; color: #000000;"> toExchage();<br/></span><span style="color: #008080;">31</span> <span style="background-color: #f5f5f5; color: #000000;"> })<br/></span><span style="color: #008080;">32</span> <br/><span style="color: #008080;">33</span> <span style="background-color: #f5f5f5; color: #008000;">//</span><span style="background-color: #f5f5f5; color: #008000;">#region 获取变换后的对象</span><br/><span style="color: #008080;">34</span> <span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> toExchage() {<br/></span><span style="color: #008080;">35</span> <br/><span style="color: #008080;">36</span> <span style="background-color: #f5f5f5; color: #000000;"> $(</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">li</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">).each(</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> (k, v) {<br/></span><span style="color: #008080;">37</span> <br/><span style="color: #008080;">38</span> <span style="background-color: #f5f5f5; color: #008000;">/*</span><br/><span style="color: #008080;">39</span> <span style="background-color: #f5f5f5; color: #008000;"> this.style.left = arr[k].left;<br/></span><span style="color: #008080;">40</span> <span style="background-color: #f5f5f5; color: #008000;"> this.style.top = arr[k].top;<br/></span><span style="color: #008080;">41</span> <span style="background-color: #f5f5f5; color: #008000;"> this.style.WebkitTransform = arr[k].scale;<br/></span><span style="color: #008080;">42</span> <span style="background-color: #f5f5f5; color: #008000;"> this.style.zIndex = arr[k].zIndex;<br/></span><span style="color: #008080;">43</span> <span style="background-color: #f5f5f5; color: #008000;">*/</span><br/><span style="color: #008080;">44</span> <br/><span style="color: #008080;">45</span> <span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> params </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> {<br/></span><span style="color: #008080;">46</span> <span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">left</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">: arr[k].left,<br/></span><span style="color: #008080;">47</span> <span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">top</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">: arr[k].top,<br/></span><span style="color: #008080;">48</span> <span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">z-index</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">: arr[k].zIndex<br/></span><span style="color: #008080;">49</span> <span style="background-color: #f5f5f5; color: #000000;"> }<br/></span><span style="color: #008080;">50</span> <br/><span style="color: #008080;">51</span> <span style="background-color: #f5f5f5; color: #000000;"> $(</span><span style="background-color: #f5f5f5; color: #0000ff;">this</span><span style="background-color: #f5f5f5; color: #000000;">).stop(</span><span style="background-color: #f5f5f5; color: #0000ff;">true</span><span style="background-color: #f5f5f5; color: #000000;">).animate(params, </span><span style="background-color: #f5f5f5; color: #000000;">200</span><span style="background-color: #f5f5f5; color: #000000;">, </span><span style="background-color: #f5f5f5; color: #000000;">'</span><span style="background-color: #f5f5f5; color: #000000;">linear</span><span style="background-color: #f5f5f5; color: #000000;">'</span><span style="background-color: #f5f5f5; color: #000000;">, </span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> () {<br/></span><span style="color: #008080;">52</span> <span style="background-color: #f5f5f5; color: #000000;"> $(</span><span style="background-color: #f5f5f5; color: #0000ff;">this</span><span style="background-color: #f5f5f5; color: #000000;">).css({ </span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">-webkit-transform</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">: arr[k].scale, </span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">transform</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">: arr[k].scale });<br/></span><span style="color: #008080;">53</span> <span style="background-color: #f5f5f5; color: #000000;"> });<br/></span><span style="color: #008080;">54</span> <br/><span style="color: #008080;">55</span> <span style="background-color: #f5f5f5; color: #000000;"> });<br/></span><span style="color: #008080;">56</span> <br/><span style="color: #008080;">57</span> <span style="background-color: #f5f5f5; color: #000000;"> }<br/></span><span style="color: #008080;">58</span> <span style="background-color: #f5f5f5; color: #008000;">//</span><span style="background-color: #f5f5f5; color: #008000;">#endregion</span><br/><span style="color: #008080;">59</span> <br/><span style="color: #008080;">60</span> <span style="background-color: #f5f5f5; color: #000000;"> }<br/></span><span style="color: #008080;">61</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span></div><p>&nbsp;</p><p>&nbsp;写完之后 我感概万分:于是乎 我挥笔写下了如下说说,遭一群逗比挖苦不堪</p><p><img src="http://images.cnitblog.com/i/149713/201407/261204592295219.jpg" alt="" /></p><img src="http://counter.cnblogs.com/blog/rss/3869864" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/zjflove/p/3869864.html" target="_blank">炎炎夏日,走入美妙的前端设计案例</a>,转载请注明。</p>http://www.cnblogs.com/ifantastic/p/3863808.html[XPath/Python] XPath 与 lxml (三)XPath 坐标轴 - iFantasticMe本章我们将沿用上一章的 XML 示例文档。XPath 坐标轴坐标轴用于定义当对当前节点的节点集合。坐标轴名称含义ancestor选取当前节点的所有先辈元素及根节点。ancestor-or-self选取当前节点的所有先辈以及当前节点本身。attibute选取当前节点的所有属性。child选取当前节点的...2014-07-26T03:53:00Z2014-07-26T03:53:00ZiFantasticMehttp://www.cnblogs.com/ifantastic/<p>本章我们将沿用上一章的 XML 示例文档。</p><p>&nbsp;</p><p><strong>XPath 坐标轴</strong></p><p>坐标轴用于定义当对当前节点的节点集合。</p><table border="0" align="left"><tbody><tr><td><strong>坐标轴名称</strong></td><td><strong>含义</strong></td></tr><tr><td>ancestor</td><td>选取当前节点的所有先辈元素及根节点。</td></tr><tr><td>ancestor-or-self</td><td>选取当前节点的所有先辈以及当前节点本身。</td></tr><tr><td>attibute</td><td>选取当前节点的所有属性。</td></tr><tr><td>child</td><td>选取当前节点的所有子元素。</td></tr><tr><td>descendant</td><td>选取当前节点的所有后代元素。</td></tr><tr><td>descendant-or-self</td><td>选取当前节点的所有后代元素以及当前节点本身。</td></tr><tr><td>following</td><td>选取文档中当前节点的结束标签之后的所有节点。</td></tr><tr><td>following-sibling</td><td>选取当前节点之后的所有同级节点</td></tr><tr><td>namespace</td><td>选取当前节点的所有命名空间节点。</td></tr><tr><td>parent</td><td>选取当前节点的父节点。</td></tr><tr><td>preceding</td><td>选取当前节点的开始标签之前的所有节点。</td></tr><tr><td>preceding-sibling</td><td>选取当前节点之前的所有同级节点。</td></tr><tr><td>self</td><td>选取当前节点。</td></tr></tbody></table><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p><strong>&nbsp;</strong></p><p><strong>位置路径表达式</strong></p><p>位置路径可以是绝对路径,也可以是相对路径。绝对路径以 "/" 开头。每条路径包括一个或多个步,每步之间以 "/" 分隔。</p><p>&nbsp;</p><p>绝对路径:/step/step/...</p><p>相对路径:step/step/...</p><p>&nbsp;</p><p>每步根据当前节点集合中的节点计算。</p><p>&nbsp;</p><p><strong>步(step)包括三部分:</strong></p><ul><li>坐标轴(axis):定义所选节点与当前节点之间的关系。</li><li>节点测试(node-test):识别某个坐标轴内部的节点。</li><li>预判(predicate):提出预判条件对节点集合进行筛选。</li></ul><p>步的语法:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">坐标轴::节点测试[预判]</div><p>&nbsp;</p><p>实例</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008000;">#</span><span style="color: #008000;"> child::nodename 选取所有属于当前节点的 book 子元素,等价于 './nodename'</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">child::book</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d888c8&gt;, &lt;Element book at 0x2d88878&gt;<span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">./book</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d888c8&gt;, &lt;Element book at 0x2d88878&gt;<span style="color: #000000;">]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> attribute::lang 选取当前节点的 lang 属性,等价于 './@lang'</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">//*[@lang]</span><span style="color: #800000;">'</span>)[0].xpath(<span style="color: #800000;">'</span><span style="color: #800000;">attribute::lang</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span><span style="color: #800000;">'</span><span style="color: #800000;">eng</span><span style="color: #800000;">'</span><span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">//*[@lang]</span><span style="color: #800000;">'</span>)[0].xpath(<span style="color: #800000;">'</span><span style="color: #800000;">@lang</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span><span style="color: #800000;">'</span><span style="color: #800000;">eng</span><span style="color: #800000;">'</span><span style="color: #000000;">]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> child::* 选取当前节点的所有子元素,等价于 './*'</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">child::*</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d88878&gt;, &lt;Element book at 0x2d88738&gt;<span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">./*</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d88878&gt;, &lt;Element book at 0x2d88738&gt;<span style="color: #000000;">]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> attribute::* 选取当前节点的所有属性,等价于 './@*'</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">//*[@*]</span><span style="color: #800000;">'</span>)[0].xpath(<span style="color: #800000;">'</span><span style="color: #800000;">attribute::*</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span><span style="color: #800000;">'</span><span style="color: #800000;">eng</span><span style="color: #800000;">'</span><span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">//*[@*]</span><span style="color: #800000;">'</span>)[0].xpath(<span style="color: #800000;">'</span><span style="color: #800000;">@*</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span><span style="color: #800000;">'</span><span style="color: #800000;">eng</span><span style="color: #800000;">'</span><span style="color: #000000;">]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> child::text() 选取当前节点的所有文本子节点,等价于 './text()'</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">child::text()</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span><span style="color: #800000;">'</span><span style="color: #800000;">\n </span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">\n </span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">\n</span><span style="color: #800000;">'</span><span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">./text()</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span><span style="color: #800000;">'</span><span style="color: #800000;">\n </span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">\n </span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">\n</span><span style="color: #800000;">'</span><span style="color: #000000;">]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> child::node() 选取当前节点所有子节点,等价于 './node()'</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">child::node()</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span><span style="color: #800000;">'</span><span style="color: #800000;">\n </span><span style="color: #800000;">'</span>, &lt;Element book at 0x2d88878&gt;, <span style="color: #800000;">'</span><span style="color: #800000;">\n </span><span style="color: #800000;">'</span>, &lt;Element book at 0x2d88738&gt;, <span style="color: #800000;">'</span><span style="color: #800000;">\n</span><span style="color: #800000;">'</span><span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">./node()</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span><span style="color: #800000;">'</span><span style="color: #800000;">\n </span><span style="color: #800000;">'</span>, &lt;Element book at 0x2d88878&gt;, <span style="color: #800000;">'</span><span style="color: #800000;">\n </span><span style="color: #800000;">'</span>, &lt;Element book at 0x2d88738&gt;, <span style="color: #800000;">'</span><span style="color: #800000;">\n</span><span style="color: #800000;">'</span><span style="color: #000000;">]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> descendant::book 选取当前节点所有 book 后代,等价于 './/book'</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">descendant::book</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d88878&gt;, &lt;Element book at 0x2d88738&gt;<span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">.//book</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d88878&gt;, &lt;Element book at 0x2d88738&gt;<span style="color: #000000;">]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> ancestor::book 选取当前节点所有 book 先辈</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">.//title</span><span style="color: #800000;">'</span>)[0].xpath(<span style="color: #800000;">'</span><span style="color: #800000;">ancestor::book</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d88878&gt;<span style="color: #000000;">]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> ancestor-or-self::book 选取当前节点的所有 book 先辈以及如果当前节点是 book 的话也要选取</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">.//title</span><span style="color: #800000;">'</span>)[0].xpath(<span style="color: #800000;">'</span><span style="color: #800000;">ancestor-or-self::book</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d88878&gt;<span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">.//book</span><span style="color: #800000;">'</span>)[0].xpath(<span style="color: #800000;">'</span><span style="color: #800000;">ancestor-or-self::book</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element book at 0x2d88878&gt;<span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">.//book</span><span style="color: #800000;">'</span>)[0].xpath(<span style="color: #800000;">'</span><span style="color: #800000;">ancestor::book</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[]<br/><br/></span><span style="color: #008000;">#</span><span style="color: #008000;"> child::*/child::price 选取当前节点的所有 price 孙节点,等价于 './*/price'</span><br/>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">child::*/child::price</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element price at 0x2d88878&gt;, &lt;Element price at 0x2d88738&gt;<span style="color: #000000;">]<br/></span>&gt;&gt;&gt; root.xpath(<span style="color: #800000;">'</span><span style="color: #800000;">./*/price</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/>[</span>&lt;Element price at 0x2d88878&gt;, &lt;Element price at 0x2d88738&gt;]</div><img src="http://counter.cnblogs.com/blog/rss/3863808" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/ifantastic/p/3863808.html" target="_blank">[XPath/Python] XPath 与 lxml (三)XPath 坐标轴</a>,转载请注明。</p>http://www.cnblogs.com/Alandre/p/3869831.html【线程管理】之篇一 - Jeff Li摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢!亲爱我,孝何难;亲恶我,孝方贤。一、简介二、简单介绍线程创建和运行三、线程信息的获取和设置四、线程中断:interrupt() 或者 使用java异常控制五、线程的休眠和恢复...2014-07-26T03:42:00Z2014-07-26T03:42:00ZJeff Lihttp://www.cnblogs.com/Alandre/<p><span style="font-size: small;">摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢!</span></p><p><strong><span style="color: #9b00d3;">亲爱我,孝何难;亲恶我,孝方贤。</span></strong></p><p><a href="#jeffli01">一、简介</a></p><p><a href="#jeffli02">二、简单介绍线程创建和运行</a></p><p><a href="#jeffli03">三、线程信息的获取和设置</a></p><p><a href="#jeffli04">四、线程中断:interrupt() 或者 使用java异常控制</a></p><p><a href="#jeffli05">五、线程的休眠和恢复</a></p><p><a href="#jeffli06">六、等待线程的终止</a></p><h1 id="jeffli01">一、简介</strong></p><p><strong>并发(Concurrency)</strong>指的是一系列任务的同时运行。如果一台电脑多个处理器或者多核处理器,这个同时性是真正意义上的并发;但一电脑只有一个单核处理器,这个同时性并不是真正的并发。</p><p><strong>线程</strong>(<strong>thread</strong>)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。<br />举个例子:在唱歌的时候,你可以同时阅读电子邮件,又可以浏览网页。这种存在着 进程级(Process-Level)并发。在浏览网页中,可以看书,视频,写日志,写博&hellip;有着多个同时进行的任务,这种进程并发任务为 线程(Thread)。</p><h1 id="jeffli02">二、简单介绍线程创建和运行</strong></p><p>java程序创建线程有两种方法:</p><ul><li>继承Thread类,覆盖run方法。</li><li>创建一个Runnable接口的类。使用带参数的Thread构造器创建Thread对象。这个参数就是实现Runnable接口的类的一个对象。</li></ul><p>用第二种方式,举个很简单的例子:Calculator.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Calculator <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable<br/>{<br/><br/> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> number;<br/><br/> </span><span style="color: #0000ff;">public</span> Calculator(<span style="color: #0000ff;">int</span><span style="color: #000000;"> number)<br/> {<br/> </span><span style="color: #0000ff;">this</span>.number =<span style="color: #000000;"> number;<br/> }<br/><br/> @Override<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run()<br/> {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt;= 10; i++<span style="color: #000000;">)<br/> {<br/> System.out.printf(</span>"%s: %d * %d = %d \n"<span style="color: #000000;">, Thread.currentThread()<br/> .getName(), number, i, i </span>*<span style="color: #000000;"> number);<br/> }<br/> }<br/><br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args)<br/> {<br/> </span><span style="color: #0000ff;">new</span> Thread(<span style="color: #0000ff;">new</span> Calculator(1<span style="color: #000000;">)).start();;<br/> }<br/>}</span></div><p>你可以看到以下输出:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;">Thread-0: 1 * 0 = 0<span style="color: #000000;"> <br/>Thread</span>-0: 1 * 1 = 1<span style="color: #000000;"> <br/>Thread</span>-0: 1 * 2 = 2<span style="color: #000000;"> <br/>Thread</span>-0: 1 * 3 = 3<span style="color: #000000;"> <br/>Thread</span>-0: 1 * 4 = 4<span style="color: #000000;"> <br/>...</span></div><p>Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:</p><ul><li>调用了 <code>Runtime</code> 类的 <code>exit</code> 方法,并且安全管理器允许退出操作发生。</li><li>非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 <code>run</code> 方法之外的异常。</li></ul><p><strong>注意:其实&nbsp; <strong>java.lang.Thread</strong><strong> 实现的接口:</strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Runnable.html">Runnable</a> 。只有当调用Thread对象的start方法,新的线程才会被创建。</strong></p><p>&nbsp;</p><p>相关资料:</p><p><strong>java.lang.Thread</strong></p><p><code><strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#Thread(java.lang.Runnable)">Thread</a></strong>(<a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Runnable.html">Runnable</a> target)</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 分配新的 <code>Thread</code> 对象。</p><p><code>void </code><code><strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#start()">start</a></strong>()</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使该线程开始执行;Java 虚拟机调用该线程的 <code>run</code> 方法。</p><p><code>static <a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html">Thread</a></code><code><strong>&nbsp;<a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#currentThread()">currentThread</a></strong>()</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回对当前正在执行的线程对象的引用。</p><p><code><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/String.html">String</a></code><code><strong>&nbsp;<a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#getName()">getName</a></strong>()</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回该线程的名称。</p><h1 id="jeffli03">三、线程信息的获取和设置</strong></p><p>Thread类有了一些保存信息的属性,这些属性用来标识线程,显示线程状态或控制线程优先级。</p><ul><li>ID: 保存了线程唯一标识符</li><li>Name: 线程名称</li><li>Priority: 线程的优先级。 1-10 最低优先级为1 最高优先级为10.</li><li>Status线程状态。线程可以处于下列状态之一: </li></ul><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.State.html#NEW"><code>NEW</code></a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 至今尚未启动的线程处于这种状态。 </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.State.html#RUNNABLE"><code>RUNNABLE</code></a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 正在 Java 虚拟机中执行的线程处于这种状态。 </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.State.html#BLOCKED"><code>BLOCKED</code></a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 受阻塞并等待某个监视器锁的线程处于这种状态。 </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.State.html#WAITING"><code>WAITING</code></a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。 </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.State.html#TIMED_WAITING"><code>TIMED_WAITING</code></a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。 </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.State.html#TERMINATED"><code>TERMINATED</code></a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 已退出的线程处于这种状态。</p><p>下面演示一个 10个线程 名称和优先级 输出他们的状态信息直到线程结束:</p><p>Calculator.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Calculator <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable<br/>{<br/><br/> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> number;<br/> </span><span style="color: #0000ff;">public</span> Calculator(<span style="color: #0000ff;">int</span><span style="color: #000000;"> number)<br/> {<br/> </span><span style="color: #0000ff;">this</span>.number =<span style="color: #000000;"> number;<br/> }<br/> @Override<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run()<br/> {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt;= 10 ; i++<span style="color: #000000;">)<br/> {<br/> System.out.printf(</span>"%s: %d * %d = %d \n", Thread.currentThread().getName(),number,i,i*<span style="color: #000000;">number);<br/> }<br/> }<br/><br/>}</span></div><p>测试代码:Main.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Main<br/>{<br/><br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args)<br/> {<br/> Thread threads[] </span>= <span style="color: #0000ff;">new</span> Thread[10<span style="color: #000000;">];<br/> Thread.State status[] </span>= <span style="color: #0000ff;">new</span> Thread.State[10<span style="color: #000000;">];<br/> <br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">)<br/> {<br/> threads[i] </span>= <span style="color: #0000ff;">new</span> Thread(<span style="color: #0000ff;">new</span><span style="color: #000000;"> Calculator(i));<br/> <br/> </span><span style="color: #0000ff;">if</span> ((i%2) == 0<span style="color: #000000;">)<br/> threads[i].setPriority(Thread.MAX_PRIORITY);<br/> </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> <br/> threads[i].setPriority(Thread.MIN_PRIORITY);<br/> <br/> threads[i].setName(</span>"Thread "+<span style="color: #000000;">i);<br/> }<br/> <br/> </span><span style="color: #0000ff;">try</span>(FileWriter file = <span style="color: #0000ff;">new</span> FileWriter(".\\log.txt"<span style="color: #000000;">);<br/> PrintWriter pw </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> PrintWriter(file);)<br/> {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">)<br/> {<br/> pw.println(</span>"Main: status of Thread "+i+" : "+<span style="color: #000000;">threads[i].getState());<br/> status[i] </span>=<span style="color: #000000;"> threads[i].getState();<br/> }<br/> <br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">)<br/> {<br/> threads[i].start();<br/> }<br/> <br/> </span><span style="color: #0000ff;">boolean</span> finish = <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">while</span> (!<span style="color: #000000;">finish)<br/> {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">)<br/> {<br/> </span><span style="color: #0000ff;">if</span> (threads[i].getState() !=<span style="color: #000000;"> status[i])<br/> {<br/> writeThreadInfo(pw , threads[i],status[i]);<br/> status[i] </span>=<span style="color: #000000;"> threads[i].getState();<br/> }<br/> }<br/> finish </span>= <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">)<br/> {<br/> finish </span>= finish &amp;&amp; (threads[i].getState() ==<span style="color: #000000;"> State.TERMINATED);<br/> }<br/> }<br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e)<br/> {<br/> e.printStackTrace();<br/> }<br/> }<br/><br/> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> writeThreadInfo(PrintWriter pw, Thread thread,<br/> State state)<br/> {<br/> pw.printf(</span>"Main: id %d - %s \n"<span style="color: #000000;">, thread.getId(),thread.getName());<br/> pw.printf(</span>"Main: Priority: %d\n"<span style="color: #000000;">, thread.getPriority());<br/> pw.printf(</span>"Main: Old state: %s \n"<span style="color: #000000;">, state);<br/> pw.printf(</span>"Main: new state: %s \n"<span style="color: #000000;">, thread.getState());<br/> pw.printf(</span>"Main: *******************************\n"<span style="color: #000000;">);<br/> }<br/><br/>}</span></div><p>你可以看到控制台 和 生成的log.txt记录者每个线程的状态演变。最高的比最低优先级的线程结束的早。</p><p><a href="http://images.cnitblog.com/blog/509099/201407/261141289168012.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="http://images.cnitblog.com/blog/509099/201407/261141293228953.png" alt="image" width="300" height="344" border="0" /></a><a href="http://images.cnitblog.com/blog/509099/201407/261141297755882.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="http://images.cnitblog.com/blog/509099/201407/261141299637825.png" alt="image" width="324" height="343" border="0" /></a></p><p><strong>注意:如果没有给线程置顶名字,JVM给分配默认格式名字:Thread-XX(XX为一组数字).同样线程ID和状态是不许改变的。线程类没提供setId() 和 setStatus()。</strong></p><p>相关资料:</p><p><strong>java.lang.Thread</strong></p><p><code>void </code><code><strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#setPriority(int)">setPriority</a></strong>(int newPriority)</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 更改线程的优先级。</p><p><code>void </code><code><strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#setName(java.lang.String)">setName</a></strong>(<a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/String.html">String</a> name)</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 改变线程名称,使之与参数 <code>name</code> 相同。</p><p><code><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.State.html">Thread.State</a></code><code><strong>&nbsp;<a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#getState()">getState</a></strong>()</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回该线程的状态。</p><h1 id="jeffli04">四、线程中断:interrupt() 或者 使用java异常控制</strong></p><p>线程中,java提供了中断机制。但是如果是复杂的算法 和 分布在几个方法中,java提供了InterruptedException一次控制线程中断。</p><p>下面各自举个例子:</p><p>第一个创建一个线程,运行5秒钟后再通过中断机制强制使其终止。</p><p>PrimeGenerator .java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> PrimeGenerator <span style="color: #0000ff;">extends</span><span style="color: #000000;"> Thread<br/>{<br/> @Override<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run()<br/> {<br/> </span><span style="color: #0000ff;">long</span> number = 1L<span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">)<br/> {<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(isPrime(number))<br/> System.out.println(</span>"Number "+number+" is Prime"<span style="color: #000000;">);<br/> <br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (isInterrupted())<br/> {<br/> System.out.println(</span>"The Prime Generator has been Interrupted"<span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ;<br/> }<br/> number</span>++<span style="color: #000000;">;<br/> }<br/> }<br/><br/> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">boolean</span> isPrime(<span style="color: #0000ff;">long</span><span style="color: #000000;"> number)<br/> {<br/> </span><span style="color: #0000ff;">if</span> (number &lt; 2<span style="color: #000000;">)<br/> </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">long</span> i = 2; i &lt; number; i++<span style="color: #000000;">)<br/> {<br/> </span><span style="color: #0000ff;">if</span> ((number % i) == 0<span style="color: #000000;">)<br/> </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> }<br/> <br/> </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/> }<br/> <br/>}</span></div><p>测试代码:Main.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Main<br/>{<br/><br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args)<br/> {<br/> Thread task </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> PrimeGenerator();<br/> task.start();<br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> Thread.sleep(</span>5000<span style="color: #000000;">);<br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e)<br/> {<br/> e.printStackTrace();<br/> }<br/> task.interrupt();<br/> }<br/>}</span></div><p>你可以观察到,5秒钟内任务在跳动,但是</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://images.cnitblog.com/blog/509099/201407/261141302757796.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="http://images.cnitblog.com/blog/509099/201407/261141305729238.png" alt="image" width="345" height="326" border="0" /></a></p><p>相关资料:</p><p><strong><strong>java.lang.Thread</strong> </strong></p><p><code>boolean </code><code><strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#isInterrupted()">isInterrupted</a></strong>()</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 测试线程是否已经中断。</p><p><code>static void </code><code><strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#sleep(long)">sleep</a></strong>(long millis)</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。</p><p><code>void </code><code><strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/Thread.html#interrupt()">interrupt</a></strong>()</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 中断线程。</p><p>&nbsp;</p><p>第二个我们用InterruptedException异常来控制线程中断。</p><p>FileSearch.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> FileSearch <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable<br/>{<br/><br/> </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String initPath;<br/> </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String fileName;<br/> <br/> </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> FileSearch(String initPath, String fileName)<br/> {<br/> </span><span style="color: #0000ff;">this</span>.initPath =<span style="color: #000000;"> initPath;<br/> </span><span style="color: #0000ff;">this</span>.fileName =<span style="color: #000000;"> fileName;<br/> }<br/><br/> @Override<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run()<br/> {<br/> File file </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> File(initPath);<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (file.isDirectory())<br/> {<br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> directoryProcess(file);<br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e)<br/> {<br/> System.out.printf(</span>"%s: The search has been interupted"<span style="color: #000000;">,Thread.currentThread().getName());<br/> }<br/> }<br/> }<br/><br/> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> directoryProcess(File file) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> InterruptedException <br/> {<br/> File list[] </span>=<span style="color: #000000;"> file.listFiles();<br/> </span><span style="color: #0000ff;">if</span> (list != <span style="color: #0000ff;">null</span><span style="color: #000000;">)<br/> {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; list.length; i++<span style="color: #000000;">)<br/> {<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (list[i].isDirectory())<br/> {<br/> directoryProcess(list[i]); <br/> }<br/> </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/> fileProcess(list[i]);<br/> }<br/> }<br/> }<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (Thread.interrupted())<br/> {<br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> InterruptedException();<br/> }<br/> }<br/> <br/> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> fileProcess(File file) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> InterruptedException<br/> {<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (file.getName().equals(fileName))<br/> {<br/> System.out.println( Thread.currentThread().getName()</span>+" : "+<span style="color: #000000;">file.getAbsolutePath());<br/> }<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (Thread.interrupted())<br/> {<br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> InterruptedException();<br/> }<br/> }<br/><br/>}</span></div><p>测试代码:Main.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">package</span><span style="color: #000000;"> sedion.jeffli.concurrency4;<br/><br/></span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.util.concurrent.TimeUnit;<br/><br/></span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Main<br/>{<br/><br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args)<br/> {<br/> FileSearch fileSearch </span>= <span style="color: #0000ff;">new</span> FileSearch("C:\\", "abc.bat"<span style="color: #000000;">);<br/> Thread thread </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Thread(fileSearch);<br/> thread.start();<br/> <br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> TimeUnit.SECONDS.sleep(</span>10<span style="color: #000000;">);<br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e)<br/> {<br/> e.printStackTrace();<br/> }<br/> thread.interrupt();<br/> }<br/>}</span></div><p>不管地用了多少次,只要线程检测到它已经中断了,立即抛出InterruptedException,继续赤星run方法。你可以看到,当输出:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://images.cnitblog.com/blog/509099/201407/261141308859209.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="http://images.cnitblog.com/blog/509099/201407/261141311043909.png" alt="image" width="405" height="111" border="0" /></a></p><h1 id="jeffli05">五、线程的休眠和恢复</strong></p><p>有时候你需要在某一个预期时间中中断线程的执行。例如像每隔一分钟检查&hellip;我们可以调用线程的sleep()方法,也可以用TimeUtil美剧累元素进行调用。</p><p>下面使用sleep()方法,每隔一秒钟就输出实际时间。</p><p>FileClock.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">package</span><span style="color: #000000;"> sedion.jeffli.concurrency5;<br/><br/></span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.util.Date;<br/></span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.util.concurrent.TimeUnit;<br/><br/></span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> FileClock <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable<br/>{<br/><br/> @Override<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run()<br/> {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">)<br/> {<br/> System.out.println(</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> Date());<br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> TimeUnit.SECONDS.sleep(</span>1<span style="color: #000000;">);<br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e)<br/> {<br/> System.out.println(</span>"The File Clock has been interrupted"<span style="color: #000000;">);<br/> }<br/> }<br/> }<br/> <br/>}</span></div><p>测试代码:FileMain.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">package</span><span style="color: #000000;"> sedion.jeffli.concurrency5;<br/><br/></span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.util.concurrent.TimeUnit;<br/><br/></span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> FileMain<br/>{<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args)<br/> {<br/> FileClock fileClock </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> FileClock();<br/> Thread thread </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Thread(fileClock);<br/> thread.start();<br/> <br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> TimeUnit.SECONDS.sleep(</span>5<span style="color: #000000;">);<br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e)<br/> {<br/> e.printStackTrace();<br/> }<br/> thread.interrupt();<br/> }<br/>}</span></div><p>你会看到如下的展示:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://images.cnitblog.com/blog/509099/201407/261141312915853.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="http://images.cnitblog.com/blog/509099/201407/261141315104851.png" alt="image" width="359" height="199" border="0" /></a></p><p><strong>最佳实践:当线程被中断时,释放或者关闭线程正在使用的资源。</strong></p><h1 id="jeffli06">六、等待线程的终止</strong></p><p><br />使用线程来完成这些初始化任务,等待线程终止,执行程序的其他任务。为了达到这个目的,我们可以用Thread类的join()方法。当一个线程对象的join方法被调用时,调用它的线程被挂起,知道这个线程对象完成他的任务。</p><p>例如 一种初始化资源 join()方法</p><p>DataSourcesLoader.java&nbsp; NetworkConnectionsLoader.java</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> DataSourcesLoader <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable<br/>{<br/><br/> @Override<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run()<br/> {<br/> System.out.println(</span>"Beginning data sources loading: "+<span style="color: #0000ff;">new</span><span style="color: #000000;"> Date());<br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> TimeUnit.SECONDS.sleep(</span>4<span style="color: #000000;">); <br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e)<br/> {<br/> e.printStackTrace();<br/> }<br/> System.out.println(</span>"Beginning data sources loading has finished: "+<span style="color: #0000ff;">new</span><span style="color: #000000;"> Date());<br/> }<br/><br/>}<br/></span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> NetworkConnectionsLoader <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable<br/>{<br/><br/> @Override<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run()<br/> {<br/> System.out.println(</span>"Beginning data sources loading: "+<span style="color: #0000ff;">new</span><span style="color: #000000;"> Date());<br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> TimeUnit.SECONDS.sleep(</span>6<span style="color: #000000;">); <br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e)<br/> {<br/> e.printStackTrace();<br/> }<br/> System.out.println(</span>"Beginning data sources loading has finished: "+<span style="color: #0000ff;">new</span><span style="color: #000000;"> Date());<br/> }<br/><br/>}</span></div><p>测试代码:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="background-color: #f5f5f5; border: #cccccc 1px solid; padding: 5px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Main<br/>{<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args)<br/> {<br/> DataSourcesLoader dataSourcesLoader </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> DataSourcesLoader();<br/> Thread thread1 </span>= <span style="color: #0000ff;">new</span> Thread(dataSourcesLoader,"DataSourcesLoader"<span style="color: #000000;">);<br/> <br/> NetworkConnectionsLoader connectionsLoader </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> NetworkConnectionsLoader();<br/> Thread thread2 </span>= <span style="color: #0000ff;">new</span> Thread(connectionsLoader,"NetworkConnectionsLoader"<span style="color: #000000;">);<br/> <br/> thread1.start();<br/> thread2.start();<br/> <br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> thread1.join();<br/> thread2.join();<br/> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e)<br/> {<br/> e.printStackTrace();<br/> }<br/> <br/> System.out.println(</span>"Main: has finished :"+<span style="color: #0000ff;">new</span><span style="color: #000000;"> Date());<br/> }<br/>}</span></div><p>这个代码你可以看到两个线程对象是如何运行的。DataSourcesLoader运行结束,直到NetworkConnectionsLoader也结束的时候,主程序的对象继续运行并打出最终的信息。</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://images.cnitblog.com/blog/509099/201407/261141318076294.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="http://images.cnitblog.com/blog/509099/201407/261141320106765.png" alt="image" width="536" height="132" border="0" /></a></p><p>相关资料:</p><p><strong><strong>java.lang.Thread </strong><strong>java.util.concurrent.TimeUnit</strong></strong></p>public final void <strong>join</strong>()<br/> throws <a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/InterruptedException.html">InterruptedException</a><dl><dd>等待该线程终止。</dd><dd><dl></dl><dl><dt><strong>抛出:</strong></dt><dd><code><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/lang/InterruptedException.html">InterruptedException</a></code> - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的<em>中断状态</em> 被清除。</dd></dl></dd></dl><p><code>void </code><code><strong><a href="mk:@MSITStore:E:%5C?????????%5CvideoForStudy%5C??????????????????????????????12???JAVAEE+??????%5C????????????%5CJDK6API????????????.chm::/java/util/concurrent/TimeUnit.html#sleep(long)">sleep</a></strong>(long timeout)</code><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用此单元执行 <tt>Thread.sleep</tt>.这是将时间参数转换为 <tt>Thread.sleep</tt> 方法所需格式的便捷方法。</p><p><strong>七、感谢知识来源和小结</strong></p><p><a href="#jeffli01">一、简介</a></p><p><a href="#jeffli02">二、简单介绍线程创建和运行</a></p><p><a href="#jeffli03">三、线程信息的获取和设置</a></p><p><a href="#jeffli04">四、线程中断:interrupt() 或者 使用java异常控制</a></p><p><a href="#jeffli05">五、线程的休眠和恢复</a></p><p><a href="#jeffli06">六、等待线程的终止</a></p><p>来自:《并发编程》《Think in java》</p><p><strong>如以上文章或链接对你有帮助的话,别忘了在文章按钮或到页面右下角点击 &ldquo;赞一个&rdquo; 按钮哦。你也可以点击页面右边&ldquo;分享&rdquo;悬浮按钮哦,让更多的人阅读这篇文章。</strong></p><p><strong><span style="color: #9b00d3;">亲有过 谏使更 怡吾色 柔吾声 谏不入 悦复谏 号泣随 挞无怨</span></strong></p><img src="http://counter.cnblogs.com/blog/rss/3869831" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/Alandre/p/3869831.html" target="_blank">【线程管理】之篇一</a>,转载请注明。</p>http://www.cnblogs.com/zhidan/p/3869743.html基于Sae和Python的flask实现的金山快盘自动签到 - zhidan第一次写博客园,各位大大请多加照顾哦。进入正题功能介绍架到Sae后,每天定点Sae的服务器就会帮你自动签到金山快盘和自动转盘抽奖。一些记录如下:金山快盘的签到记录:Sae的Cron的日记:核心代码本来想写抓包的过程的,但是感觉很小儿科(如果大家觉得有需要,我再写上来),就不献丑了,直接po上代码。 ...2014-07-26T02:42:00Z2014-07-26T02:42:00Zzhidanhttp://www.cnblogs.com/zhidan/<p>第一次写博客园,各位大大请多加照顾哦。</p><p>进入正题</p><p><strong>功能介绍</strong></p><p>架到Sae后,每天定点Sae的服务器就会帮你自动签到金山快盘和自动转盘抽奖。一些记录如下:</p><p>&nbsp;金山快盘的签到记录:</p><p><img src="http://images.cnitblog.com/i/478748/201407/260934570579399.png" alt="" /></p><p>Sae的Cron的日记:</p><p><img src="http://images.cnitblog.com/i/478748/201407/260935263856606.jpg" alt="" /></p><p><strong>核心代码</strong></p><p>本来想写抓包的过程的,但是感觉很小儿科(如果大家觉得有需要,我再写上来),就不献丑了,直接po上代码。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> 1 #!/usr/bin/python <br/> 2 #-*-coding:utf-8-*- <br/> 3 import<span> urllib, urllib2, cookielib, sys<br/> 4 <br/> 5 class<span> kuaipan:<br/> 6 userName = ''<br/> 7 password = ''<br/> 8 cookie =<span> None<br/> 9 <br/>10 def __init__<span>(self, userName, pwd):<br/>11 self.userName =<span> userName<br/>12 self.password =<span> pwd<br/>13 self.cookie =<span> cookielib.LWPCookieJar()<br/>14 opener =<span> urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie))<br/>15 <span> urllib2.install_opener(opener)<br/>16 <br/>17 def<span> login(self):<br/>18 #测试获取cookies<br/>19 req = urllib2.Request(url='https://www.kuaipan.cn/account_login.htm'<span>)<br/>20 <span> urllib2.urlopen(req)<br/>21 <br/>22 postdata = {'username':self.userName,'userpwd':self.password,'isajax':'yes'<span>}<br/>23 postdata =<span> urllib.urlencode(postdata)<br/>24 print 'Logining...'<br/>25 req = urllib2.Request(url='http://www.kuaipan.cn/index.php?ac=account&amp;op=login', data=postdata)<br/>26 response =<span> urllib2.urlopen(req)<br/>27 <br/>28 #保存cookie<br/>29 response =<span> urllib2.urlopen(req)<br/>30 print<span> response.url<br/>31 print '登陆成功,准备签到'<br/>32 <br/>33 def<span> signIn(self):<br/>34 print 'signing...'<br/>35 req = urllib2.Request(url='http://www.kuaipan.cn/index.php?ac=common&amp;op=usersign'<span>)<br/>36 result =<span> urllib2.urlopen(req).read()<br/>37 print<span> result<br/>38 print '签到成功'<br/>39 <br/>40 def<span> turnplatel(self):<br/>41 print 'turnplate...'<br/>42 req = urllib2.Request(url='http://www.kuaipan.cn/turnplate/lottery/'<span>)<br/>43 result =<span> urllib2.urlopen(req).read()<br/>44 print<span> result<br/>45 print '抽奖成功'</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div><p>&nbsp;上面这个代码是自动签到的核心代码,大家想单独的运行(不搭建在Sae)的话,可以在最后加上Main方法,如下</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">if __name__ == '__main__'<span>:<br/> user = kuaipan('userName', 'Password'<span>) <br/> user.login()<br/> user.signIn()<br/> user.turnplatel() </span></span></div><p><strong>搭建到Sae</strong></p><p>如何搭建Sae以及如何Svn上传代码到Sae里,这里不再细说。</p><p>由于写这个(快盘自动签到)的功能比较小,所以我选择了flask框架(我不是说这个框架没用,只能写小东西哦)。</p><p>对于flask框架,我是从这个网站学习的:<a href="http://www.pythondoc.com/flask-mega-tutorial/index.html" target="_blank">http://www.pythondoc.com/flask-mega-tutorial/index.html</a></p><p>有兴趣的可以自己去看看,没兴趣的,待会直接看我po上来的代码,聪明的你也会明白的。</p><p>&nbsp;链接:&nbsp;<a href="http://pan.baidu.com/s/1dDEeOvf" target="_blank">http://pan.baidu.com/s/1dDEeOvf</a>&nbsp;密码: 8dyh</p><p>1、不想架到Sae的,自行导入Eclipse后右键运行run.py(需要安装pyDev插件)或者自己控制台运行也行。</p><p>然后浏览器进入<a href="http://127.0.0.1:5000/signin_kuaipan" target="_blank">http://127.0.0.1:5000/signin_kuaipan</a></p><p>如果看到页面返回&ldquo;签到成功&rdquo;,说明运行成功。</p><p>2、想架到Sae的同学,我在配置文件中已经帮你写好了cron,你只要上传到Sae里,就可以看到定时任务已经存在了。可以在Sae的&nbsp;<strong>服务管理</strong>&nbsp;里的&nbsp;<strong>cron</strong>&nbsp;找到。<a href="http://sae.sina.com.cn/?m=cronmng&amp;app_id=netsignin&amp;ver=1"><br /></a></p><p>&nbsp;</p><p><strong>最后</strong></p><p>第一次写博客,感谢大家的浏览。写之前搜了一下博客园的博客,拔了一份模板,感谢<a href="http://www.cnblogs.com/twobin/p/3473737.html" target="_blank">twobin</a>提供的模板</p><p>我对cron不熟悉,哪位大大能够告诉我怎么实现一段时间内随机执行任务cron,非常感谢。</p><img src="http://counter.cnblogs.com/blog/rss/3869743" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/zhidan/p/3869743.html" target="_blank">基于Sae和Python的flask实现的金山快盘自动签到</a>,转载请注明。</p>http://www.cnblogs.com/ganiks/p/cygwin-and-host-machine.htmlcygwin and its host machine - GaniksSenario---本来我是想要修改下 `machine name`在Ubuntu中的步骤是这样的```1 sudo hostname newMechineName2 sudo vi /etc/hostname 把原来的机器名改为新的 newMechineName3 sudo vi /etc/ho....2014-07-26T02:10:00Z2014-07-26T02:10:00ZGanikshttp://www.cnblogs.com/ganiks/<h2 id="senario">Senario</strong></p><p>本来我是想要修改下 <code>machine name</code></p><p>在Ubuntu中的步骤是这样的</p><code>1 sudo hostname newMechineName<br/>2 sudo vi /etc/hostname<br/>  把原来的机器名改为新的 newMechineName<br/>3 sudo vi /etc/hosts<br/>  修改 127.0.1.1 对应的计算机名为新的计算机名称</code><p>先要修改下 hosts 文件</p><p>因为刚用 cygwin, 对系统不是很熟, 只是以为 cygwin 系统是一个封闭的系统放在宿主机器的某个文档夹里面</p><p>经过此次发掘,搞清楚 cygwin 和 host machine 的关系</p><code>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ gvim /etc/hosts<br/><br/>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ ll /etc/hosts<br/>lrwxrwxrwx 1 Administrators root 46 Jul 25 13:34 /etc/hosts -&gt; /cygdrive/c/WINDOWS/system32/drivers/etc/hosts<br/><br/>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ vim /etc/hosts<br/>/cygdrive/d/Program Files/Git/bin/vim: line 3: /share/vim/vim74/vim: No such file or directory<br/>/cygdrive/d/Program Files/Git/bin/vim: line 3: exec: /share/vim/vim74/vim: cannot execute: No such file or directory<br/>#无法打开<br/>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ vi /etc/hosts<br/>#正常打开<br/>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ gvim /etc/hosts<br/>#这里打开文件时空的</code><h2 id="cygwin--">cygwin中用的 命令/程序 都来自哪里?</strong></p><p>只有 vi 可以打开 <code>/etc/hosts</code></p><p>ok, 问题明白了, 就是权限问题</p><p>要搞清楚 vi, vim, gvim 分别是属于哪里的就明白了</p><ul><li>vi<br /></li><li>vim<br /></li><li>gvim</li></ul><code>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ whereis.exe vi<br/>vi: /usr/bin/vi.exe /cygdrive/d/Program Files/Git/bin/vi<br/><br/>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ whereis.exe vim<br/>vim: /cygdrive/d/Program Files/Git/bin/vim /cygdrive/d/Program Files/Vim/vim74/vim.exe<br/><br/>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ whereis.exe gvim<br/>gvim: /cygdrive/d/Program Files/Vim/vim74/gvim.exe<br/><br/>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$</code><h2 id="-cygwin-chmod-chown">让 cygwin 系统支持权限(chmod, chown)</strong></p><p>说到权限, 这里还有一点要注意</p><p>最开始我的 cygwin 装在 E:\ 盘上, 当时 E:\ 的格式是 <code>Fat32</code></p><p>然后用到 <code>chmod</code> 命令的时候失效 :参考另一篇文章</p><p><a href="http://www.cnblogs.com/ganiks/p/cygwin-chmod-not-support.html"><a href="http://www.cnblogs.com/ganiks/p/cygwin-chmod-not-support.html">http://www.cnblogs.com/ganiks/p/cygwin-chmod-not-support.html</a></a></p><p>转换为 <code>NTFS</code> 格式之后, 支持了权限的管理, 有个细节要注意到就是所有文档的 USER:GROUP 变化啦</p><code>drwxr-xr-x 1 ganiks.liu Domain Users 0 Jul 25 13:28 .<br/>drwxr-xr-x 1 ganiks.liu Domain Users 0 Jul 25 13:10 ..<br/>drwxr-xr-x 1 ganiks.liu Domain Users 0 Jul 25 13:49 uscreens<br/><br/># 转换 NTFS 之后<br/>ganiks.liu@MAMIS-Gaiks-Liu /tmp<br/>$ ll<br/>total 0<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 .<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:10 ..<br/>drwxrwxrwx+ 1 ganiks.liu root 0 Jul 25 13:49 uscreens<br/><br/>ganiks.liu@MAMIS-Gaiks-Liu /tmp<br/>$</code><h2 id="cygwin-">cygwin 跟宿主系统的关系是什么?</strong></p><code>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ ll /etc/<br/>total 537<br/>drwxrwx---+ 1 Administrators root 0 Jul 26 08:45 .<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:10 ..<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 alternatives<br/>-rwxrwx---+ 1 Administrators root 856 Jul 25 13:35 bash.bash_logout<br/>-rwxrwx---+ 1 Administrators root 1176 Jul 25 13:35 bash.bashrc<br/>-rwxrwx---+ 1 Administrators root 58352 Feb 12 2011 bash_completion<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 bash_completion.d<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 dbus-1<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 defaults<br/>-rwxrwx---+ 1 Administrators root 5023 Jul 25 13:34 DIR_COLORS<br/>-rwxrwx---+ 1 Administrators root 3095 Jul 22 11:00 drirc<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:29 fonts<br/>-rwxrwx---+ 1 Administrators root 192 Jul 25 13:34 fstab<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:34 fstab.d<br/>-rwxrwx---+ 1 Administrators root 560 Jul 25 13:34 group<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:29 gtk-2.0<br/>lrwxrwxrwx 1 Administrators root 46 Jul 25 13:34 hosts -&gt; /cygdrive/c/WINDOWS/system32/drivers/etc/hosts<br/>-rwxrwx---+ 1 Administrators root 149610 May 8 2012 lynx.cfg<br/>-rwxrwx---+ 1 Administrators root 3583 May 8 2012 lynx.lss<br/>-rwxrwx---+ 1 Administrators root 66 Jul 25 13:35 lynx-site.cfg<br/>-rwxrwx---+ 1 Administrators root 5135 Jul 25 13:35 man_db.conf<br/>-rwxrwx---+ 1 Administrators root 242153 May 24 02:59 moduli<br/>lrwxrwxrwx 1 Administrators root 12 Jul 25 13:34 mtab -&gt; /proc/mounts<br/>lrwxrwxrwx 1 Administrators root 49 Jul 25 13:34 networks -&gt; /cygdrive/c/WINDOWS/system32/drivers/etc/networks<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:35 pango<br/>-rwxrwx---+ 1 Administrators root 943 Jul 25 13:34 passwd<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:30 pkcs11<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 pki<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 postinstall<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 preremove<br/>-rwxrwx---+ 1 Administrators root 7634 Jul 25 13:35 profile<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 profile.d<br/>lrwxrwxrwx 1 Administrators root 50 Jul 25 13:34 protocols -&gt; /cygdrive/c/WINDOWS/system32/drivers/etc/protocols<br/>-rwxrwx---+ 1 Administrators root 51799 Jul 25 13:34 rebase.db.i386<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:30 sasl2<br/>lrwxrwxrwx 1 Administrators root 49 Jul 25 13:34 services -&gt; /cygdrive/c/WINDOWS/system32/drivers/etc/services<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:10 setup<br/>-rwxrwx---+ 1 Administrators root 210 Jul 25 13:35 shells<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:35 skel<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:28 ssl<br/>-rwxrwx---+ 1 Administrators root 4795 Jul 25 13:46 wgetrc<br/>drwxrwx---+ 1 Administrators root 0 Jul 25 13:35 xml</code><p>看看 <code>hosts -&gt; /cygdrive/c/WINDOWS/system32/drivers/etc/hosts</code></p><p>明白了吧, 原来想要访问宿主系统, 只需要进入到 <code>/cygdrive/</code> 目录下 !</p><blockquote><p>越是想要了解一个东西,越是不能放过任何一个小小的疑问<br />这里就是因为想要修改 machine name 就让我发现这么重要的一个对 cygwin 认知。</p></blockquote><h2 id="-hostname">最终没有修改成功 hostname</strong></p><code>ganiks.liu@MAMIS-Gaiks-Liu ~<br/>$ hostname.exe wswtech<br/>hostname: cannot set hostname; this system lacks the functionality<br/></code><p>介绍一篇不错的 cygwin 入门教程:</p><p><a href="http://w.gdu.me/wiki/cygwin/index.html"><a href="http://w.gdu.me/wiki/cygwin/index.html">http://w.gdu.me/wiki/cygwin/index.html</a></a></p><img src="http://counter.cnblogs.com/blog/rss/3869611" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/ganiks/p/cygwin-and-host-machine.html" target="_blank">cygwin and its host machine</a>,转载请注明。</p>http://www.cnblogs.com/kenshincui/p/3869639.htmlIOS开发系列--Objective-C之协议、代码块、分类 - KenshinCuiObjC的语法主要基于smalltalk进行设计的,除了提供常规的面向对象特性外,还增加了很多其他特性,这一节将重点介绍ObjC中一些常用的语法特性。当然这些内容虽然和其他高级语言命名不一样,但是我们都可以在其中找到他们的影子,在文章中我也会对比其他语言进行介绍,这一节的重点内容如下:协议proto...2014-07-26T01:52:00Z2014-07-26T01:52:00ZKenshinCuihttp://www.cnblogs.com/kenshincui/<p><strong>概述</strong></p> <p>ObjC的语法主要基于smalltalk进行设计的,除了提供常规的面向对象特性外,还增加了很多其他特性,这一节将重点介绍ObjC中一些常用的语法特性。当然这些内容虽然和其他高级语言命名不一样,但是我们都可以在其中找到他们的影子,在文章中我也会对比其他语言进行介绍,这一节的重点内容如下:</p> <ol> <li><a href="#protocol">协议protocol</a> <li><a href="#block">代码块block</a> <li><a href="#category">分类category</a></li></ol> <h1 id="protocol">协议protocol</strong></p> <p>在ObjC中使用@protocol定义一组方法规范,实现此协议的类必须实现对应的方法。熟悉面向对象的童鞋都知道接口本身是对象行为描述的协议规范。也就是说在ObjC中@protocol和其他语言的接口定义是类似的,只是在ObjC中interface关键字已经用于定义类了,因此它不会再像C#、Java中使用interface定义接口了。</p> <p>假设我们定义了一个动物的协议AnimalDelegate,人员Person这个类需要实现这个协议,请看下面的代码:</p> <p>AnimalDelegate.h</p><span style="background: white; color: green">//<br/>// AnimalDelegate.h<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/><br/>//定义一个协议<br/></span><span style="background: white; color: black">@protocol AnimalDelegate &lt;NSObject&gt;<br/><br/>@required </span><span style="background: white; color: green">//必须实现的方法<br/></span><span style="background: white; color: black">-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)eat;<br/><br/>@optional </span><span style="background: white; color: green">//可选实现的方法<br/></span><span style="background: white; color: black">-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)run;<br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)say;<br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)sleep;<br/><br/>@end</span><p>&nbsp;</p><p>Person.h</p><a href="http://11011.net/software/vspaste"></a><span style="background: white; color: green">//<br/>// Person.h<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">&lt;Foundation/Foundation.h&gt;<br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"AnimalDelegate.h"<br/><br/></span><span style="background: white; color: black">@</span><span style="background: white; color: blue">interface </span><span style="background: white; color: black">Person : NSObject&lt;AnimalDelegate&gt;<br/><br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)eat;<br/><br/>@end</span><p>Person.m</p><span style="background: white; color: green">//<br/>// Person.m<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"Person.h"<br/><br/></span><span style="background: white; color: black">@implementation Person<br/><br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)eat{<br/> NSLog(@</span><span style="background: white; color: #a31515">"eating..."</span><span style="background: white; color: black">);<br/>}<br/><br/>@end</span><p>这里需要说明几点:</p><ol><li>一个协议可以扩展自另一个协议,例如上面AnimalDelegate就扩展自NSObject,如果需要扩展多个协议中间使用逗号分隔; <li>和其他高级语言中接口不同的是协议中定义的方法不一定是必须实现的,我们可以通过关键字进行@required和@optional进行设置,如果不设置则默认是@required(注意ObjC是弱语法,即使不实现必选方法编译运行也不会报错); <li>协议通过&lt;&gt;进行实现,一个类可以同时实现多个协议,中间通过逗号分隔; <li>协议的实现只能在类的声明上(.h),不能放到类的实现上(Person.m中不能实现); <li>协议中的方法可以在类声明文件.h中声明,也可以不声明直接在.m中实现,如果只实现不声明则认为是私有方法; <li>协议中不能定义属性、成员变量等,只能定义方法; </li></ol><p>事实上在ObjC中协议的更多作用是用于约束一个类必须实现某些方法,而从面向对象的角度而言这个类跟接口并不一定存在某种自然关系,可能是两个完全不同意义上的事物,这种模式我们称之为代理模式(Delegation)。在Cocoa框架中大量采用这种模式实现数据和UI的分离,而且基本上所有的协议都是以Delegate结尾。</p><p>现在假设需要设计一个按钮,我们知道按钮都是需要点击的,在其他语言中通常会引入事件机制,只要使用者订阅了点击事件,那么点击的时候就会触发执行这个事件(这是对象之间解耦的一种方式:代码注入)。但是在ObjC中没有事件的定义,而是使用代理来处理这个问题。首先在按钮中定义按钮的代理,同时使用协议约束这个代理(事件的触发者)必须实现协议中的某些方法,当按钮处理过程中查看代理是否实现了这个方法,如果实现了则调用这个方法。</p><p>KCButton.h</p><span style="background: white; color: green">//<br/>// KCButton.h<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">&lt;Foundation/Foundation.h&gt;<br/></span><span style="background: white; color: black">@</span><span style="background: white; color: blue">class </span><span style="background: white; color: black">KCButton;<br/><br/></span><span style="background: white; color: green">//一个协议可以扩展另一个协议,例如KCButtonDelegate扩展了NSObject协议<br/></span><span style="background: white; color: black">@protocol KCButtonDelegate &lt;NSObject&gt;<br/><br/>@required </span><span style="background: white; color: green">//@required修饰的方法必须实现<br/></span><span style="background: white; color: black">-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)onClick:(KCButton *)button;<br/><br/>@optional </span><span style="background: white; color: green">//@optional修饰的方法是可选实现的<br/></span><span style="background: white; color: black">-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)onMouseover:(KCButton *)button;<br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)onMouseout:(KCButton *)button;<br/><br/>@end<br/><br/>@</span><span style="background: white; color: blue">interface </span><span style="background: white; color: black">KCButton : NSObject<br/><br/></span><span style="background: white; color: blue">#pragma </span><span style="background: white; color: black">mark - 属性<br/></span><span style="background: white; color: blue">#pragma </span><span style="background: white; color: black">mark 代理属性,同时约定作为代理的对象必须实现KCButtonDelegate协议<br/>@</span><span style="background: white; color: blue">property </span><span style="background: white; color: black">(nonatomic,retain) id&lt;KCButtonDelegate&gt; </span><span style="background: white; color: blue">delegate</span><span style="background: white; color: black">;<br/><br/></span><span style="background: white; color: blue">#pragma </span><span style="background: white; color: black">mark - 公共方法<br/></span><span style="background: white; color: blue">#pragma </span><span style="background: white; color: black">mark 点击方法<br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)click;<br/><br/>@end</span><p>KCButton.m</p><span style="background: white; color: green">//<br/>// KCButton.m<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"KCButton.h"<br/><br/></span><span style="background: white; color: black">@implementation KCButton<br/><br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)click{<br/> NSLog(@</span><span style="background: white; color: #a31515">"Invoke KCButton's click method."</span><span style="background: white; color: black">);<br/> </span><span style="background: white; color: green">//判断_delegate实例是否实现了onClick:方法(注意方法名是"onClick:",后面有个:)<br/> //避免未实现ButtonDelegate的类也作为KCButton的监听<br/> </span><span style="background: white; color: blue">if</span><span style="background: white; color: black">([_delegate respondsToSelector:@selector(onClick:)]){<br/> [_delegate onClick:self];<br/> }<br/>}<br/><br/>@end</span><p>MyListener.h</p><span style="background: white; color: green">//<br/>// MyListener.h<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">&lt;Foundation/Foundation.h&gt;<br/></span><span style="background: white; color: black">@</span><span style="background: white; color: blue">class </span><span style="background: white; color: black">KCButton;<br/>@protocol KCButtonDelegate;<br/><br/>@</span><span style="background: white; color: blue">interface </span><span style="background: white; color: black">MyListener : NSObject&lt;KCButtonDelegate&gt;<br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)onClick:(KCButton *)button;<br/>@end</span><p>MyListener.m</p><span style="background: white; color: green">//<br/>// MyListener.m<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"MyListener.h"<br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"KCButton.h"<br/><br/></span><span style="background: white; color: black">@implementation MyListener<br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)onClick:(KCButton *)button{<br/> NSLog(@</span><span style="background: white; color: #a31515">"Invoke MyListener's onClick method.The button is:%@."</span><span style="background: white; color: black">,button);<br/>}<br/>@end</span><a href="http://11011.net/software/vspaste"></a><p>main.m</p><span style="background: white; color: green">//<br/>// main.m<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">&lt;Foundation/Foundation.h&gt;<br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"KCButton.h"<br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"MyListener.h"<br/><br/></span><span style="background: white; color: blue">int </span><span style="background: white; color: black">main(</span><span style="background: white; color: blue">int </span><span style="background: white; color: black">argc, </span><span style="background: white; color: blue">const char </span><span style="background: white; color: black">* argv[]) {<br/> @autoreleasepool {<br/> <br/> KCButton *button=[[KCButton alloc]init];<br/> MyListener *listener=[[MyListener alloc]init];<br/> button.</span><span style="background: white; color: blue">delegate</span><span style="background: white; color: black">=listener;<br/> [button click];<br/> </span><span style="background: white; color: green">/* 结果:<br/> Invoke KCButton's click method.<br/> Invoke MyListener's onClick method.The button is:&lt;KCButton: 0x1001034c0&gt;.<br/> */<br/> </span><span style="background: white; color: black">}<br/> </span><span style="background: white; color: blue">return </span><span style="background: white; color: black">0;<br/>}</span><a href="http://11011.net/software/vspaste"></a><p>我们通过例子模拟了一个按钮的点击过程,有点类似于Java中事件的实现机制。通过这个例子我们需要注意以下几点内容:</p><ol><li>id可以表示任何一个ObjC对象类型,类型后面的”&lt;协议名&gt;“用于约束作为这个属性的对象必须实现该协议(注意:使用id定义的对象类型不需要加“*”); <li>MyListener作为事件触发者,它实现了KCButtonDelegate代理(在ObjC中没有命名空间和包的概念,通常通过前缀进行类的划分,“KC”是我们自定义的前缀) <li>在.h文件中如果使用了另一个文件的类或协议我们可以通过@class或者@protocol进行声明,而不必导入这个文件,这样可以提高编译效率(注意有些情况必须使用@class或@protocol,例如上面KCButton.h中上面声明的KCButtonDelegate协议中用到了KCButton类,而此文件下方的KCButton类声明中又使用了KCButtonDelegate,从而形成在一个文件中互相引用关系,此时必须使用@class或者@protocol声明,否则编译阶段会报错),但是在.m文件中则必须导入对应的类声明文件或协议文件(如果不导入虽然语法检查可以通过但是编译链接会报错); <li>使用respondsToSelector方法可以判断一个对象是否实现了某个方法(需要注意方法名不是”onClick”而是“onClick:”,冒号也是方法名的一部分);</li></ol><blockquote><p>属性中的(nonatomic,retain)不是这篇文章的重点,在接下来的文章中我们会具体介绍。</p></blockquote><h1 id="block">代码块Block</strong></p><p>在C#异步编程时我们经常进行函数回调,由于函数调用是异步执行的,我们如果想让一个操作执行完之后执行另一个函数,则无法按照正常代码书写顺序进行编程,因为我们无法获知前一个方法什么时候执行结束,此时我们经常会用到匿名委托或者lambda表达式将一个操作作为一个参数进行传递。其实在ObjC中也有类似的方法,称之为代码块(Block)。Block就是一个函数体(匿名函数),它是ObjC对于闭包的实现,在块状中我们可以持有或引用局部变量(不禁想到了lambda表达式),同时利用Block你可以将一个操作作为一个参见进行传递(是不是想起了C语言中的函数指针)。在下面的例子中我们将使用Block实现上面的点击监听操作:</p><p>KCButton.h</p><span style="background: white; color: green">//<br/>// KCButton.h<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">&lt;Foundation/Foundation.h&gt;<br/></span><span style="background: white; color: black">@</span><span style="background: white; color: blue">class </span><span style="background: white; color: black">KCButton;<br/></span><span style="background: white; color: blue">typedef void</span><span style="background: white; color: black">(^KCButtonClick)(KCButton *);<br/><br/>@</span><span style="background: white; color: blue">interface </span><span style="background: white; color: black">KCButton : NSObject<br/><br/></span><span style="background: white; color: blue">#pragma </span><span style="background: white; color: black">mark - 属性<br/></span><span style="background: white; color: blue">#pragma </span><span style="background: white; color: black">mark 点击操作属性<br/>@</span><span style="background: white; color: blue">property </span><span style="background: white; color: black">(nonatomic,assign) KCButtonClick onClick;<br/></span><span style="background: white; color: green">//上面的属性定义等价于下面的代码<br/>//@property (nonatomic,assign) void(^ onClick)(KCButton *);<br/><br/></span><span style="background: white; color: blue">#pragma </span><span style="background: white; color: black">mark - 公共方法<br/></span><span style="background: white; color: blue">#pragma </span><span style="background: white; color: black">mark 点击方法<br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)click;<br/>@end</span><a href="http://11011.net/software/vspaste"></a><p>KCButton.m</p><span style="background: white; color: green">//<br/>// KCButton.m<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"KCButton.h"<br/><br/><br/></span><span style="background: white; color: black">@implementation KCButton<br/><br/>-(</span><span style="background: white; color: blue">void</span><span style="background: white; color: black">)click{<br/> NSLog(@</span><span style="background: white; color: #a31515">"Invoke KCButton's click method."</span><span style="background: white; color: black">);<br/> </span><span style="background: white; color: blue">if </span><span style="background: white; color: black">(_onClick) {<br/> _onClick(self);<br/> }<br/>}<br/><br/>@end</span><a href="http://11011.net/software/vspaste"></a><p>main.m</p><span style="background: white; color: green">//<br/>// main.m<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">&lt;Foundation/Foundation.h&gt;<br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"KCButton.h"<br/><br/><br/></span><span style="background: white; color: blue">int </span><span style="background: white; color: black">main(</span><span style="background: white; color: blue">int </span><span style="background: white; color: black">argc, </span><span style="background: white; color: blue">const char </span><span style="background: white; color: black">* argv[]) {<br/><br/> KCButton *button=[[KCButton alloc]init];<br/> button.onClick=^(KCButton *btn){<br/> NSLog(@</span><span style="background: white; color: #a31515">"Invoke onClick method.The button is:%@."</span><span style="background: white; color: black">,btn);<br/> };<br/> [button click];<br/> </span><span style="background: white; color: green">/*结果:<br/> Invoke KCButton's click method.<br/> Invoke onClick method.The button is:&lt;KCButton: 0x1006011f0&gt;.<br/> */<br/> <br/> <br/> </span><span style="background: white; color: blue">return </span><span style="background: white; color: black">0;<br/>}</span><a href="http://11011.net/software/vspaste"></a><p>上面代码中使用Block同样实现了按钮的点击事件,关于Block总结如下:</p><ol><li>Block类型定义:<font color="#ff0000"><strong>返回值类型(^ 变量名)(参数列表)</strong><font color="#404040">,如果参数为空,则传入void(注意Block也是一种类型);</font></font> <li><font color="#ff0000"><font color="#404040">Block的typedef定义:</font><strong>返回值类型(^类型名称)(参数列表)</strong></font><font color="#404040">,如果参数为空则传入void;</font> <li>Block的实现:<font color="#ff0000"><strong>^(参数列表){操作主体}</strong></font><font color="#404040">,如果参数为空则传入void;</font> <li><font color="#404040">Block在栈上存储(通过上面onClick变量没有加“*”和assign修饰也可以印证);</font></li></ol><h1 id="category">分类Category</strong></p><p><font color="#404040">当我们不改变原有代码为一个类扩展其他功能时我们可以考虑继承这个类进行实现,但是这样一来使用时就必须定义成新实现的子类才能拥有扩展的新功能。如何在不改变原有类的情况下扩展新功能又可以在使用时不必定义新类型呢?我们知道如果在C#中可以使用扩展方法,其实在ObjC中也有类似的实现,就是分类Category。利用分类,我们就可以在ObjC中动态的为已有类添加新的行为(特别是系统或框架中的类)。在C#中字符串有一个Trim()方法用于去掉字符串前后的空格,使用起来特别方便,但是在ObjC中却没有这个方法,这里我们不妨通过Category给NSString添加一个stringByTrim()方法:</font></p><p><font color="#404040">NSString+Extend.h</font></p><span style="background: white; color: green">//<br/>// NSString+Extend.h<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">&lt;Foundation/Foundation.h&gt;<br/><br/></span><span style="background: white; color: black">@</span><span style="background: white; color: blue">interface </span><span style="background: white; color: black">NSString (Extend)<br/>-(NSString *)stringByTrim;<br/>@end</span><a href="http://11011.net/software/vspaste"></a><p><font color="#404040">NSString+Extend.m</font></p><span style="background: white; color: green">//<br/>// NSString+Extend.m<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"NSString+Extend.h"<br/><br/></span><span style="background: white; color: black">@implementation NSString (Extend)<br/>-(NSString *)stringByTrim{<br/> NSCharacterSet *character= [NSCharacterSet whitespaceCharacterSet];<br/> </span><span style="background: white; color: blue">return </span><span style="background: white; color: black">[self stringByTrimmingCharactersInSet:character];<br/>}<br/>@end</span><a href="http://11011.net/software/vspaste"></a><p><font color="#404040">main.m</font></p><span style="background: white; color: green">//<br/>// main.m<br/>// Protocol&amp;Block&amp;Category<br/>//<br/>// Created by Kenshin Cui on 14-2-2.<br/>// Copyright (c) 2014年 Kenshin Cui. All rights reserved.<br/>//<br/><br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">&lt;Foundation/Foundation.h&gt;<br/></span><span style="background: white; color: blue">#import </span><span style="background: white; color: #a31515">"NSString+Extend.h"<br/><br/><br/></span><span style="background: white; color: blue">int </span><span style="background: white; color: black">main(</span><span style="background: white; color: blue">int </span><span style="background: white; color: black">argc, </span><span style="background: white; color: blue">const char </span><span style="background: white; color: black">* argv[]) {<br/><br/> NSString *name=@</span><span style="background: white; color: #a31515">" Kenshin Cui "</span><span style="background: white; color: black">;<br/> name=[name stringByTrim];<br/> NSLog(@</span><span style="background: white; color: #a31515">"I'm %@!"</span><span style="background: white; color: black">,name); </span><span style="background: white; color: green">//结果:I'm Kenshin Cui!<br/> <br/> </span><span style="background: white; color: blue">return </span><span style="background: white; color: black">0;<br/>}</span><a href="http://11011.net/software/vspaste"></a><p><font color="#404040"></font></p><p>通过上面的输出结果我们可以看出已经成功将@” Kenshin Cui ”两端的空格去掉了。分类文件名一般是“原有类名+分类名称”,分类的定义是通过在原有类名后加上”(分类名)”来定义的(注意声明文件.h和实现文件.m都是如此)。</p><img src="http://counter.cnblogs.com/blog/rss/3869639" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/kenshincui/p/3869639.html" target="_blank">IOS开发系列--Objective-C之协议、代码块、分类</a>,转载请注明。</p>http://www.cnblogs.com/anmutu/p/3869580.html这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧。 - 杜少.这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧。 假设现在有如下情况,某项目的框架结构用的是ADO.NET写的简单三层。且已经开始写了一部分了。现在因为时间比较紧急,经理认为用EF写速度会快一些,于是要求我们将访问驱动层改成用EF写的。 那么,恩,好吧,我们得改.....2014-07-26T01:01:00Z2014-07-26T01:01:00Z杜少.http://www.cnblogs.com/anmutu/<p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧。</span></p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp; &nbsp; 假设现在有如下情况,某项目的框架结构用的是ADO.NET写的简单三层。且已经开始写了一部分了。现在因为时间比较紧急,经理认为用EF写速度会快一些,于是要求我们将访问驱动层改成用EF写的。</span></p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp; 那么,恩,好吧,我们得改了。先看一下原来DAL层和BLL层的代码。因仅演示而已,此处只写了一个大概思路的代码。另外此处笔者只打算写一个DAL层了BLL层的一个松耦合的一个渐近过程的处理。方法只写一个。诸位见谅。主要是要有那个思路。</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('de72582b-477f-4ccd-b1bd-9df1f1616644')"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"></span><div id="cnblogs_code_open_de72582b-477f-4ccd-b1bd-9df1f1616644" class="cnblogs_code_hide"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.Model;<br/></span><span style="color: #008080;"> 7</span> <br/><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> Anmutu.OA.AdoNetDAL<br/></span><span style="color: #008080;"> 9</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">10</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> UserAdoNetDal<br/></span><span style="color: #008080;">11</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">12</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> User AddUser(User user)<br/></span><span style="color: #008080;">13</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">14</span> <span style="color: #008000;">//</span><span style="color: #008000;">在此处写一此插入的一个SQL.会用到DBSQLHelper.using()...写就是一个insert操作。你知道的,主要是那个思想。代码略过。</span><br/><span style="color: #008080;">15</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">16</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">17</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">18</span> }</span></div><span class="cnblogs_code_collapse" style="font-family: comic sans ms,sans-serif; font-size: 16px;">访问驱动层的代码</span></div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('0192b4bd-be9b-47c3-bb82-27569b365cd5')"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"></span><div id="cnblogs_code_open_0192b4bd-be9b-47c3-bb82-27569b365cd5" class="cnblogs_code_hide"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.AdoNetDAL;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.Model;<br/></span><span style="color: #008080;"> 8</span> <br/><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> Anmutu.OA.BLL<br/></span><span style="color: #008080;">10</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">11</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> UserService<br/></span><span style="color: #008080;">12</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">13</span> <span style="color: #008000;">//</span><span style="color: #008000;">调用一下数据库访问层的方法,打个酱油。</span><br/><span style="color: #008080;">14</span> <span style="color: #0000ff;">private</span> AdoNetDAL.UserAdoNetDal userAdoNetDal = <span style="color: #0000ff;">new</span><span style="color: #000000;"> UserAdoNetDal();<br/></span><span style="color: #008080;">15</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> User Add(User user)<br/></span><span style="color: #008080;">16</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">17</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> userAdoNetDal.AddUser(user);<br/></span><span style="color: #008080;">18</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">19</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">20</span> }</span></div><span class="cnblogs_code_collapse" style="font-family: comic sans ms,sans-serif; font-size: 16px;">逻辑层的代码</span></div><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还好还好,DB里有的相应的表的。我们DBFirst一下,拿到EF的上下文。那么新的访问驱动层的代码将会是这个样子的:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('ebf869e0-6f93-4dd0-895c-7dd3df5a2721')"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"></span><div id="cnblogs_code_open_ebf869e0-6f93-4dd0-895c-7dd3df5a2721" class="cnblogs_code_hide"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.Model;<br/></span><span style="color: #008080;"> 7</span> <br/><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> Anmutu.OA.DAL<br/></span><span style="color: #008080;"> 9</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">10</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> UserEFDal<br/></span><span style="color: #008080;">11</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">12</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> User AddUser(User user)<br/></span><span style="color: #008080;">13</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">14</span> <span style="color: #008000;">//</span><span style="color: #008000;">得到的EF上下文,DBFirst不用解释了吧。</span><br/><span style="color: #008080;">15</span> AnmutuModelContainer db = <span style="color: #0000ff;">new</span><span style="color: #000000;"> AnmutuModelContainer();<br/></span><span style="color: #008080;">16</span> <span style="color: #008000;">//</span><span style="color: #008000;">加到DB里去。</span><br/><span style="color: #008080;">17</span> <span style="color: #000000;"> db.UserSet.Add(user);<br/></span><span style="color: #008080;">18</span> <span style="color: #008000;">//</span><span style="color: #008000;">保存</span><br/><span style="color: #008080;">19</span> <span style="color: #000000;"> db.SaveChanges();<br/></span><span style="color: #008080;">20</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> user;<br/></span><span style="color: #008080;">21</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">22</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">23</span> }</span></div><span class="cnblogs_code_collapse" style="font-family: comic sans ms,sans-serif; font-size: 16px;">EF作为访问驱动层时的代码</span></div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('b938d807-e633-4d85-a0d6-b2d90e0cd1e1')"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"></span><div id="cnblogs_code_open_b938d807-e633-4d85-a0d6-b2d90e0cd1e1" class="cnblogs_code_hide"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.AdoNetDAL;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">using</span> Anmutu.OA.DAL;<span style="color: #008000;">//</span><span style="color: #008000;">添加EF层的程序集。</span><br/><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.Model;<br/></span><span style="color: #008080;"> 9</span> <br/><span style="color: #008080;">10</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> Anmutu.OA.BLL<br/></span><span style="color: #008080;">11</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">12</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> UserService<br/></span><span style="color: #008080;">13</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">14</span> <span style="color: #0000ff;">#region</span> 用EF作为访问驱动层时的代码。<br/><span style="color: #008080;">15</span> <span style="color: #0000ff;">private</span> DAL.UserEFDal _userEfDal = <span style="color: #0000ff;">new</span><span style="color: #000000;"> UserEFDal();<br/></span><span style="color: #008080;">16</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> User AddUser(User user)<br/></span><span style="color: #008080;">17</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">18</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> _userEfDal.AddUser(user);<br/></span><span style="color: #008080;">19</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">20</span> <span style="color: #0000ff;">#endregion</span><br/><span style="color: #008080;">21</span> <span style="color: #0000ff;">#region</span> 用ADO.NET作为访问驱动层时的代码<br/><span style="color: #008080;">22</span> <span style="color: #008000;">//</span><span style="color: #008000;">private AdoNetDAL.UserAdoNetDal userAdoNetDal = new UserAdoNetDal();<br/></span><span style="color: #008080;">23</span> <span style="color: #008000;">//</span><span style="color: #008000;">public User Add(User user)<br/></span><span style="color: #008080;">24</span> <span style="color: #008000;">//</span><span style="color: #008000;">{<br/></span><span style="color: #008080;">25</span> <span style="color: #008000;">//</span><span style="color: #008000;"> return userAdoNetDal.AddUser(user);<br/></span><span style="color: #008080;">26</span> <span style="color: #008000;">//</span><span style="color: #008000;">}</span><br/><span style="color: #008080;">27</span> <span style="color: #0000ff;">#endregion</span><br/><span style="color: #008080;">28</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">29</span> }</span></div><span class="cnblogs_code_collapse" style="font-size: 16px; font-family: comic sans ms,sans-serif;">修改后的逻辑层的代码(注意对比)</span></div><p class="p0">&nbsp;</p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这样貌似就算是修改好了。在这个小案例中。那么两个分析一下具体的情况。现在的情况是逻辑层的的代码,依赖与一个具体的实现,那么依赖者就必须跟着变化。就如同这里的实例名字不一样,那么下面具体用到此实例的时候就都得改了。如果这里调用数据库访问层的方法的名字不一样,同样也是需要改动的。目前这个小案例中,修改的地方还真就不算多。但是,正如你知道的,一个项目中不可能真的只有这么一个方法的。会有很多方法。那么,是的,你得修改很多的地方了。来图看一下,它可能是这样。&nbsp;</span></p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; <img src="http://images.cnitblog.com/i/532336/201407/260841385417565.jpg" alt="" /></span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;</span></p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 程序猿甲说,这个好办,我们可以CTRL+F,然后选择将相应的需要改的全部替换也就好了。</span></p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 攻城狮乙说,这个方法,固然可以,可是如果哪个地方替换错了,就有那么一个地方名字一样,替换错误了,那岂不是很麻烦么?</span></p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 程序猿丙说,我们可以依旧CTRL+F,我们选择单个替换就好了呀,我们可以小心一点的。</span></p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 攻城狮丁说,这个方法,依旧且算可以,只是就算你很小心没有替换错,不是很耽误时间的么?时间可就是金钱啊。</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么,思路是我们就可以<span style="background-color: #ffffff; color: #ff0000;"><strong>不让其依赖与一个具体的实例。而是依赖与一个抽象的实例。比如让其依赖与一个接口。用接口解除其对具体数据库访问的耦合。通过让BLL层去依赖一个公共的变化很少的契约接口,依赖抽象,具体的实现在变化的时候,BLL层就不用变化了。</strong></span>这是对变化点的一个封装。有点绕口且有点&lsquo;WHERE IS 南 WHERE IS 北&rsquo;(笔者用此句表示不太容易理解,如果没有了解过接口神马的) 的感觉。简单的说就是用一个抽象的实例,但是后面new出来的就是一个具体的了。</span></p><p class="p0"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么,将修改的代码将会是这个样子:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('c83d7daf-07b3-4ad0-a8ff-389e774a105b')"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"></span><div id="cnblogs_code_open_c83d7daf-07b3-4ad0-a8ff-389e774a105b" class="cnblogs_code_hide"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.ComponentModel;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.Model;<br/></span><span style="color: #008080;"> 8</span> <br/><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> Anmutu.OA.IDAL<br/></span><span style="color: #008080;">10</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">11</span> <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;summary&gt;</span><br/><span style="color: #008080;">12</span> <span style="color: #808080;">///</span><span style="color: #008000;"> 创建一个接口,约定其返回类型是User类,参数是一个user实体。<br/></span><span style="color: #008080;">13</span> <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;/summary&gt;</span><br/><span style="color: #008080;">14</span> <span style="color: #0000ff;">interface</span><span style="color: #000000;"> IUserDal<br/></span><span style="color: #008080;">15</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">16</span> <span style="color: #000000;"> User AddUser(User user);<br/></span><span style="color: #008080;">17</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">18</span> }</span></div><span class="cnblogs_code_collapse" style="font-family: comic sans ms,sans-serif; font-size: 16px;">DAL层接口的约束</span></div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('e3061556-6411-46c5-b721-d54ac74f6482')"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"></span><div id="cnblogs_code_open_e3061556-6411-46c5-b721-d54ac74f6482" class="cnblogs_code_hide"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.IDAL;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.Model;<br/></span><span style="color: #008080;"> 8</span> <br/><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> Anmutu.OA.AdoNetDAL<br/></span><span style="color: #008080;">10</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">11</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> UserAdoNetDal:IUserDal<span style="color: #008000;">//</span><span style="color: #008000;">此处实现接口里的方法。因为接口里的方法名字也就AddUser,这里就没有必要CTRL+SHIFT+...了。我用的是Resharper插件,也就不用点实现了。</span><br/><span style="color: #008080;">12</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">13</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> User AddUser(User user)<br/></span><span style="color: #008080;">14</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">15</span> <span style="color: #008000;">//</span><span style="color: #008000;">在此处写一此插入的一个SQL.会用到DBSQLHelper.using()...写就是一个insert操作。</span><br/><span style="color: #008080;">16</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">17</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">18</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">19</span> }</span></div><span class="cnblogs_code_collapse" style="font-family: comic sans ms,sans-serif; font-size: 16px;">ADO.NET作为访问驱动层实现接口</span></div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('1bd27def-06f7-4b49-927f-4c138be1a06d')"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"></span><div id="cnblogs_code_open_1bd27def-06f7-4b49-927f-4c138be1a06d" class="cnblogs_code_hide"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.IDAL;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.Model;<br/></span><span style="color: #008080;"> 8</span> <br/><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> Anmutu.OA.DAL<br/></span><span style="color: #008080;">10</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">11</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> UserEFDal:IUserDal<span style="color: #008000;">//</span><span style="color: #008000;">这里实现接口。</span><br/><span style="color: #008080;">12</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">13</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> User AddUser(User user)<br/></span><span style="color: #008080;">14</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">15</span> <span style="color: #008000;">//</span><span style="color: #008000;">得到的EF上下文,DBFirst不用解释了吧。</span><br/><span style="color: #008080;">16</span> AnmutuModelContainer db = <span style="color: #0000ff;">new</span><span style="color: #000000;"> AnmutuModelContainer();<br/></span><span style="color: #008080;">17</span> <span style="color: #008000;">//</span><span style="color: #008000;">加到DB里去。</span><br/><span style="color: #008080;">18</span> <span style="color: #000000;"> db.UserSet.Add(user);<br/></span><span style="color: #008080;">19</span> <span style="color: #008000;">//</span><span style="color: #008000;">保存</span><br/><span style="color: #008080;">20</span> <span style="color: #000000;"> db.SaveChanges();<br/></span><span style="color: #008080;">21</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> user;<br/></span><span style="color: #008080;">22</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">23</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">24</span> }</span></div><span class="cnblogs_code_collapse" style="font-family: comic sans ms,sans-serif; font-size: 16px;">EF作为访问驱动层实现接口</span></div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('72ca1638-531b-4c16-98f9-de8e7f714d69')"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"></span><div id="cnblogs_code_open_72ca1638-531b-4c16-98f9-de8e7f714d69" class="cnblogs_code_hide"><span style="font-family: comic sans ms,sans-serif; font-size: 16px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.AdoNetDAL;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">using</span> Anmutu.OA.DAL;<span style="color: #008000;">//</span><span style="color: #008000;">添加EF层的程序集。</span><br/><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">using</span><span style="color: #000000;"> Anmutu.OA.Model;<br/></span><span style="color: #008080;"> 9</span> <br/><span style="color: #008080;">10</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> Anmutu.OA.BLL<br/></span><span style="color: #008080;">11</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">12</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> UserService<br/></span><span style="color: #008080;">13</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">14</span> <span style="color: #0000ff;">#region</span> 实现接口后的代码<br/><span style="color: #008080;">15</span> <span style="color: #008000;">//</span><span style="color: #008000;">IDAL.IUserDal userDal=new UserAdoNetDal();</span><span style="color: #008000;">//</span><span style="color: #008000;">当要用到ADO.NET作为访问驱动时。</span><br/><span style="color: #008080;">16</span> IDAL.IUserDal userDal=<span style="color: #0000ff;">new</span> UserEFDal();<span style="color: #008000;">//</span><span style="color: #008000;">当要用到EF作为访问驱动时。</span><br/><span style="color: #008080;">17</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> User AddUser(User user)<br/></span><span style="color: #008080;">18</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">19</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> userDal.AddUser(user);<br/></span><span style="color: #008080;">20</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">21</span> <span style="color: #0000ff;">#endregion</span><br/><span style="color: #008080;">22</span> <span style="color: #0000ff;">#region</span> 用EF作为访问驱动层时的代码。<br/><span style="color: #008080;">23</span> <span style="color: #008000;">//</span><span style="color: #008000;">private DAL.UserEFDal _userEfDal = new UserEFDal();<br/></span><span style="color: #008080;">24</span> <span style="color: #008000;">//</span><span style="color: #008000;">public User AddUser(User user)<br/></span><span style="color: #008080;">25</span> <span style="color: #008000;">//</span><span style="color: #008000;">{<br/></span><span style="color: #008080;">26</span> <span style="color: #008000;">//</span><span style="color: #008000;"> return _userEfDal.AddUser(user);<br/></span><span style="color: #008080;">27</span> <span style="color: #008000;">//</span><span style="color: #008000;">}</span><br/><span style="color: #008080;">28</span> <span style="color: #0000ff;">#endregion</span><br/><span style="color: #008080;">29</span> <span style="color: #0000ff;">#region</span> 用ADO.NET作为访问驱动层时的代码<br/><span style="color: #008080;">30</span> <span style="color: #008000;">//</span><span style="color: #008000;">private AdoNetDAL.UserAdoNetDal userAdoNetDal = new UserAdoNetDal();<br/></span><span style="color: #008080;">31</span> <span style="color: #008000;">//</span><span style="color: #008000;">public User Add(User user)<br/></span><span style="color: #008080;">32</span> <span style="color: #008000;">//</span><span style="color: #008000;">{<br/></span><span style="color: #008080;">33</span> <span style="color: #008000;">//</span><span style="color: #008000;"> return userAdoNetDal.AddUser(user);<br/></span><span style="color: #008080;">34</span> <span style="color: #008000;">//</span><span style="color: #008000;">}</span><br/><span style="color: #008080;">35</span> <span style="color: #0000ff;">#endregion</span><br/><span style="color: #008080;">36</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">37</span> }</span></div><span class="cnblogs_code_collapse" style="font-family: comic sans ms,sans-serif; font-size: 16px;">BLL层的代码(注意对比)</span></div><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp; 如果要换访问驱动层的话,请看图:</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <img src="http://images.cnitblog.com/i/532336/201407/260845497911808.jpg" alt="" /></span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 是的,只需要在如图的位置new一个不同的就好了。且VS会给我们提示。</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧。</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 攻城狮戊说,可是我可能会有很多服务的地方都用到这个实例,那我都得改么?这样写很麻烦的感觉呢。</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 李宁说过一句话,他说,一切皆有可能。所以,是的,也许以后园子时会多一篇叫做&ldquo;这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的简单工厂了吧&rdquo;的文章。</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 笔者写的都是很简单的东西。欢迎指正,共同进步。</span></p><p><span style="font-family: comic sans ms,sans-serif; font-size: 16px;">&nbsp;</span></p><img src="http://counter.cnblogs.com/blog/rss/3869580" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/anmutu/p/3869580.html" target="_blank">这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧。</a>,转载请注明。</p>http://www.cnblogs.com/f1194361820/p/3869552.htmlSpring源码阅读:Spring WebApplicationContext初始化与消亡 - 螺 丝 钉使用SpringMVC时,需要不论是使用注解配置,还是使用XML配置Bean,他们都会在Web服务器启动后就初始化。根据J2ee的知识可以知道,肯定是使用了ServletContextListener才完成的这个功能。那Spring又是如何实现的呢?还有我们在Web.xml配置的那些applicat...2014-07-26T00:28:00Z2014-07-26T00:28:00Z螺 丝 钉http://www.cnblogs.com/f1194361820/<p>&nbsp;</p><p>使用SpringMVC时,需要不论是使用注解配置,还是使用XML配置Bean,他们都会在Web服务器启动后就初始化。根据J2ee的知识可以知道,肯定是使用了ServletContextListener才完成的这个功能。那Spring又是如何实现的呢?还有我们在Web.xml配置的那些applicationContext.xml相关的XML文件的位置(配置方式多样),又是如何读取到相应的文件的呢,读取到这些文件后,是如何初始化类的呢?我们能不能自定义初始化过程或者自定义WebApplicationContext呢?WebApplicationContext消亡时又做了哪些事情呢?带着这些疑问,就来查阅一下Spring的源码。</p><p>&nbsp;</p><p><strong>找ServletContextListener</strong></p><p>&nbsp;&nbsp;&nbsp; 在使用SpringMVC时,都会配置一个监听器:</p><p>org.springframework.web.context.ContextLoaderListener,这个监听器应该就是我们要找的那个ServletContextListener吧?</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">1</span> <span style="color: #008000;">/*</span><br/><span style="color: #008080;">2</span> <span style="color: #008000;">Bootstrap listener to start up and shut down Spring's root WebApplicationContext. Simply delegates to ContextLoader as well as to ContextCleanupListener.<br/></span><span style="color: #008080;">3</span> <br/><span style="color: #008080;">4</span> <span style="color: #008000;">This listener should be registered after org.springframework.web.util.Log4jConfigListener in web.xml, if the latter is used.<br/></span><span style="color: #008080;">5</span> <br/><span style="color: #008080;">6</span> <span style="color: #008000;">*/</span> <br/><span style="color: #008080;">7</span> <br/><span style="color: #008080;">8</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> ContextLoaderListener <span style="color: #0000ff;">extends</span> ContextLoader <span style="color: #0000ff;">implements</span> ServletContextListener</div><p>&nbsp;</p><p>根据ContextLoaderListener的定义和说明来看,确实是我们要找的。因为说明中提到:这个监听器用于启动和关闭Spring的<code><strong>WebApplicationContext</strong></code><code><strong>(也就是WebApplicationContextd 初始化和消亡)</strong></code><code>。但是启动和关闭的动作并不是由这个监听器来实现的它只是一个委托。</code></p><p>&nbsp;</p><p>另外还提到:如果在web.xml要使用<code>Log4jConfigListener</code><code>,那么应该将Log4jConfigListener放在</code>ContextLoaderListener的前面。</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 根据这个类的说明,可以知道这个监听器就是我们要找的那个ServletContextListener。那么根据它顺藤摸瓜,应该就能知道如何构造WebApplicationContext的)。</p><p><img src="http://images.cnitblog.com/i/512650/201407/260826492291955.x-png" alt="" /></p><p>&nbsp;</p><p>接下来看看contextInitialized:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> contextInitialized(ServletContextEvent event) {<br/><br/> </span><span style="color: #0000ff;">this</span>.contextLoader =<span style="color: #000000;"> createContextLoader();<br/><br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.contextLoader == <span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br/><br/> </span><span style="color: #0000ff;">this</span>.contextLoader = <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.contextLoader.initWebApplicationContext(event.getServletContext());<br/><br/> }</span></div><p>&nbsp;</p><p>初始化WebApplicationContext的工作是在initWebApplicationContext完成的。</p><p>&nbsp;</p><p><strong>如何初始化WebApplicationContext</strong></p><p>&nbsp;</p><p><strong>可以在web.xml设置的相关配置</strong></p><p>在了解initWebApplicationContext中做了什么事之前,先来了解一下ContextLoader可以做什么:</p><p>&middot;这个类用于初始化WebApplicationContext,并且是在ContextLoaderListener中调用初始化。</p><p>&nbsp;</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008000;">/**</span><span style="color: #008000;"><br/> * Performs the actual initialization work for the root application context.<br/> * Called by {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> ContextLoaderListener}.<br/> *<br/> * &lt;p&gt;Looks for a {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> #CONTEXT_CLASS_PARAM "contextClass"} parameter<br/> * at the &lt;code&gt;web.xml&lt;/code&gt; context-param level to specify the context<br/> * class type, falling back to the default of<br/> * {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> org.springframework.web.context.support.XmlWebApplicationContext}<br/> * if not found. With the default ContextLoader implementation, any context class<br/> * specified needs to implement the ConfigurableWebApplicationContext interface.<br/> *<br/> * &lt;p&gt;Processes a {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> #CONFIG_LOCATION_PARAM "contextConfigLocation"}<br/> * context-param and passes its value to the context instance, parsing it into<br/> * potentially multiple file paths which can be separated by any number of<br/> * commas and spaces, e.g. "WEB-INF/applicationContext1.xml,<br/> * WEB-INF/applicationContext2.xml". Ant-style path patterns are supported as well,<br/> * e.g. "WEB-INF/*Context.xml,WEB-INF/spring*.xml" or "WEB-INF/&amp;#42;&amp;#42;/*Context.xml".<br/> * If not explicitly specified, the context implementation is supposed to use a<br/> * default location (with XmlWebApplicationContext: "/WEB-INF/applicationContext.xml").<br/> *<br/> * &lt;p&gt;Note: In case of multiple config locations, later bean definitions will<br/> * override ones defined in previously loaded files, at least when using one of<br/> * Spring's default ApplicationContext implementations. This can be leveraged<br/> * to deliberately override certain bean definitions via an extra XML file.<br/> *<br/> * &lt;p&gt;Above and beyond loading the root application context, this class<br/> * can optionally load or obtain and hook up a shared parent context to<br/> * the root application context. See the<br/> * {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> #loadParentContext(ServletContext)} method for more information.<br/></span><span style="color: #008000;">*/</span></div><p>&nbsp;</p><p>从类的说明中,可以了解到,会涉及到下列的context-param配置:</p><p>1、<span style="color: #3366ff;"><strong>contextClass</strong></span>:</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 初始化时,会先在web.xml中&lt;context-param&gt;中查找有没有一个叫做contextClass的配置。这个配置是用于自定义WebApplicationContext的实现类(自定义的WebApplicationContext的实现类,必须实现ConfigurableWebApplicationContext接口,这是为什么呢?答案将在下文中找到)。如果没有指定这个上下文参数,就默认使用XmlWebApplicationContext。</p><p>&nbsp;</p><p>2、<span style="color: #3366ff;"><strong>contextConfigLocation</strong></span></p><p>这个参数用于applicationContext*.xml文件的位置。</p><p>在这个配置中,可以设置多个文件:</p><p>&nbsp;</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">context-param</span><span style="color: #0000ff;">&gt;</span><br/><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">param-name</span><span style="color: #0000ff;">&gt;</span>contextConfigLocation<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">param-name</span><span style="color: #0000ff;">&gt;</span><br/><br/><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">param-value</span><span style="color: #0000ff;">&gt;</span>WEB-INF/applicationContext1.xml,WEB-INF/applicationContext2.xml<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">param-value</span><span style="color: #0000ff;">&gt;</span><br/><br/><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">context-param</span><span style="color: #0000ff;">&gt;</span></div><p>&nbsp;</p><p>多个配置文件之间可以用<span style="color: #ff0000;">逗号</span>或者<span style="color: #ff0000;">空格</span>区分。</p><p>也可以用WEB-INF/*Context.xml,WEB-INF/spring*.xml这样的通配符方式设置。</p><p>&nbsp;</p><p>如果不在context-param中设定contextConfigLocation:就使用默认值<span style="color: #ff0000;">:/WEB-INF/applicationContext.xml</span></p><p>&nbsp;</p><p>另外:在实际的项目中,如果指定了多个applicationContext.xml文件,在这么多个文件中,如有&lt;bean&gt;重名,就会自动的让后面的覆盖前面的。</p><p>&nbsp;</p><p>此外,这两个参数名是固定的,因为:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">final</span> String CONTEXT_CLASS_PARAM = "contextClass"<span style="color: #000000;">;<br/><br/></span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">final</span> String CONFIG_LOCATION_PARAM = "contextConfigLocation";</div><p>&nbsp;</p><p><strong>webApplicationContext初始化过程</strong></p><p>&nbsp;</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">public</span><span style="color: #000000;"> WebApplicationContext initWebApplicationContext(ServletContext servletContext) {<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 先判断是否已经初始化过了</span><br/><br/> <span style="color: #0000ff;">if</span> (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != <span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br/><br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> IllegalStateException(<br/><br/> </span>"Cannot initialize context because there is already a root application context present - " +<br/><br/> "check whether you have multiple ContextLoader* definitions in your web.xml!"<span style="color: #000000;">);<br/><br/> }<br/><br/> <br/><br/> Log logger </span>= LogFactory.getLog(ContextLoader.<span style="color: #0000ff;">class</span><span style="color: #000000;">);<br/><br/> servletContext.log(</span>"Initializing Spring root WebApplicationContext"<span style="color: #000000;">);<br/><br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (logger.isInfoEnabled()) {<br/><br/> logger.info(</span>"Root WebApplicationContext: initialization started"<span style="color: #000000;">);<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">long</span> startTime =<span style="color: #000000;"> System.currentTimeMillis();<br/><br/> <br/><br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 看看有没有父上下文,如果有就会将父上下问的信息合并到本上下文中<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Determine parent for root web application context, if any.</span><br/><span style="color: #000000;"><br/> ApplicationContext parent </span>=<span style="color: #000000;"> loadParentContext(servletContext);<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Store context in local instance variable, to guarantee that<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> it is available on ServletContext shutdown.</span><br/><span style="color: #000000;"><br/>这行代码就是包含Spring加载并初始化bean的调用:<br/><br/> </span><span style="color: #0000ff;">this</span>.context =<span style="color: #000000;"> createWebApplicationContext(servletContext, parent);<br/><br/> servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.context);<br/><br/> <br/><br/> ClassLoader ccl </span>=<span style="color: #000000;"> Thread.currentThread().getContextClassLoader();<br/><br/> </span><span style="color: #0000ff;">if</span> (ccl == ContextLoader.<span style="color: #0000ff;">class</span><span style="color: #000000;">.getClassLoader()) {<br/><br/> currentContext </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">.context;<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (ccl != <span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br/><br/> currentContextPerThread.put(ccl, </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.context);<br/><br/> }<br/><br/> <br/><br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (logger.isDebugEnabled()) {<br/><br/> logger.debug(</span>"Published root WebApplicationContext as ServletContext attribute with name [" +<span style="color: #000000;"><br/><br/> WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE </span>+ "]"<span style="color: #000000;">);<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (logger.isInfoEnabled()) {<br/><br/> </span><span style="color: #0000ff;">long</span> elapsedTime = System.currentTimeMillis() -<span style="color: #000000;"> startTime;<br/><br/> logger.info(</span>"Root WebApplicationContext: initialization completed in " + elapsedTime + " ms"<span style="color: #000000;">);<br/><br/> }<br/><br/> <br/><br/> </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">.context;<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (RuntimeException ex) {<br/><br/> logger.error(</span>"Context initialization failed"<span style="color: #000000;">, ex);<br/><br/> servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);<br/><br/> </span><span style="color: #0000ff;">throw</span><span style="color: #000000;"> ex;<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Error err) {<br/><br/> logger.error(</span>"Context initialization failed"<span style="color: #000000;">, err);<br/><br/> servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);<br/><br/> </span><span style="color: #0000ff;">throw</span><span style="color: #000000;"> err;<br/><br/> }<br/><br/> }</span></div><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>接下来看看如何创建WebApplicationContext实例的:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">protected</span><span style="color: #000000;"> WebApplicationContext createWebApplicationContext(ServletContext sc, ApplicationContext parent) {<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 判断自定义的WebContextContext类是否实现了ConfigurableWebApplicationContext接口:</span><br/><span style="color: #000000;"><br/> Class</span>&lt;?&gt; contextClass =<span style="color: #000000;"> determineContextClass(sc);<br/><br/> </span><span style="color: #0000ff;">if</span> (!ConfigurableWebApplicationContext.<span style="color: #0000ff;">class</span><span style="color: #000000;">.isAssignableFrom(contextClass)) {<br/><br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ApplicationContextException("Custom context class [" + contextClass.getName() +<br/><br/> "] is not of type [" + ConfigurableWebApplicationContext.<span style="color: #0000ff;">class</span>.getName() + "]"<span style="color: #000000;">);<br/><br/> }<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 利用反射创建WebApplicationContext实现类对象</span><br/><span style="color: #000000;"><br/> ConfigurableWebApplicationContext wac </span>=<span style="color: #000000;"><br/><br/> (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Assign the best possible id value.</span><br/><br/> <span style="color: #0000ff;">if</span> (sc.getMajorVersion() == 2 &amp;&amp; sc.getMinorVersion() &lt; 5<span style="color: #000000;">) {<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Servlet &lt;= 2.4: resort to name specified in web.xml, if any.</span><br/><span style="color: #000000;"><br/> String servletContextName </span>=<span style="color: #000000;"> sc.getServletContextName();<br/><br/> wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX </span>+<span style="color: #000000;"><br/><br/> ObjectUtils.getDisplayString(servletContextName));<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Servlet 2.5's getContextPath available!</span><br/><br/> <span style="color: #0000ff;">try</span><span style="color: #000000;"> {<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 通过反射调用getContextPath方法。<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 怎么老感觉Java中的反射调用方法与JavaScript中的YourFunction.call(caller,params)是那么的相像呢,不过他们的本质是不一样的。</span><br/><span style="color: #000000;"><br/> String contextPath </span>= (String) ServletContext.<span style="color: #0000ff;">class</span>.getMethod("getContextPath"<span style="color: #000000;">).invoke(sc);<br/><br/> wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX </span>+<span style="color: #000000;"><br/><br/> ObjectUtils.getDisplayString(contextPath));<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception ex) {<br/><br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> IllegalStateException("Failed to invoke Servlet 2.5 getContextPath method"<span style="color: #000000;">, ex);<br/><br/> }<br/><br/> }<br/><br/> <br/><br/> wac.setParent(parent);<br/><br/> wac.setServletContext(sc);<br/><br/> wac.setConfigLocation(sc.getInitParameter(CONFIG_LOCATION_PARAM));<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 自定义的ContextLoader可以重写这个方法,以添加一些赋值工作。<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 使用了Template方法模式</span><br/><span style="color: #000000;"><br/> customizeContext(sc, wac);<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 这里是真正的初始化配置的bean的操作。</span><br/><span style="color: #000000;"><br/> wac.<span style="color: #ff0000; font-size: 16px;">refresh</span>();<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> wac;<br/><br/> }</span></div><p>&nbsp;</p><p>这样整个WebApplicationContext就创建完毕了。</p><p>&nbsp;</p><p><strong>如何指定默认的WebApplicationContext的呢</strong></p><p>&nbsp;</p><p>在上面的创建上下文的过程中,没有指定默认的WebApplicationContext呀,它是怎么办到呢?</p><p>查看类中的代码发现一个静态代码块:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">static</span><span style="color: #000000;"> {<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Load default strategy implementations from properties file.<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> This is currently strictly internal and not meant to be customized<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> by application developers.</span><br/><br/> <span style="color: #0000ff;">try</span><span style="color: #000000;"> {<br/><br/> ClassPathResource resource </span>= <span style="color: #0000ff;">new</span> ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.<span style="color: #0000ff;">class</span><span style="color: #000000;">);<br/><br/> defaultStrategies </span>=<span style="color: #000000;"> PropertiesLoaderUtils.loadProperties(resource);<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (IOException ex) {<br/><br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> IllegalStateException("Could not load 'ContextLoader.properties': " +<span style="color: #000000;"> ex.getMessage());<br/><br/> }<br/><br/> }</span></div><p>&nbsp;</p><p>这里就是在初始化ContextLoader的实例,也就是ContextLoaderListener的实例时,就会先制定一个默认的WebApplicationContext 了。它使用了一个properties文件:ContextLoader.properties,文件的位置:</p><p>&nbsp;<img src="http://images.cnitblog.com/i/512650/201407/260818112442369.x-png" alt="" /></p><p>文件中只有一条配置:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext</div><p>&nbsp;</p><p>也就是说默认使用了XmlWebApplicationContext的。</p><p>&nbsp;</p><p><strong>ContextLoader提供的辅助功能:</strong></p><p>&nbsp;</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> WebApplicationContext getCurrentWebApplicationContext() {<br/><br/> ClassLoader ccl </span>=<span style="color: #000000;"> Thread.currentThread().getContextClassLoader();<br/><br/> </span><span style="color: #0000ff;">if</span> (ccl != <span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br/><br/> WebApplicationContext ccpt </span>=<span style="color: #000000;"> currentContextPerThread.get(ccl);<br/><br/> </span><span style="color: #0000ff;">if</span> (ccpt != <span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ccpt;<br/><br/> }<br/><br/> }<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> currentContext;<br/><br/> }<br/> </span></div><p>&nbsp;</p><p>这样一来,我们就可以在程序中直接获取WebApplicationContext对象了。</p><p><strong>初始化beans</strong></p><p>&nbsp;&nbsp;&nbsp; 经过上面的查阅,知道默认是使用XmlWebApplicationContext作为上下文的,那么这个类中肯定包含了初始化beans的过程。上面的分析知道,使用了refresh()方法初始化的。</p><p>&nbsp;</p><p>再查看refresh()方法前,先来看看对于XmlWebApplicationContext的说明,这是很有必要的,说明中提到了:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008000;">/**</span><span style="color: #008000;"><br/> * {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> org.springframework.web.context.WebApplicationContext} implementation<br/> * which takes its configuration from XML documents, understood by an<br/> * {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.<br/> * This is essentially the equivalent of<br/> * {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> org.springframework.context.support.AbstractXmlApplicationContext}<br/> * for a web environment.<br/> *<br/> * &lt;p&gt;By default, the configuration will be taken from "/WEB-INF/applicationContext.xml"<br/> * for the root context, and "/WEB-INF/test-servlet.xml" for a context with the namespace<br/> * "test-servlet" (like for a DispatcherServlet instance with the servlet-name "test").<br/> *<br/> * &lt;p&gt;The config location defaults can be overridden via the "contextConfigLocation"<br/> * context-param of {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> org.springframework.web.context.ContextLoader} and servlet<br/> * init-param of {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> org.springframework.web.servlet.FrameworkServlet}. Config locations<br/> * can either denote concrete files like "/WEB-INF/context.xml" or Ant-style patterns<br/> * like "/WEB-INF/*-context.xml" (see {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> org.springframework.util.PathMatcher}<br/> * javadoc for pattern details).<br/> *<br/> * &lt;p&gt;Note: In case of multiple config locations, later bean definitions will<br/> * override ones defined in earlier loaded files. This can be leveraged to<br/> * deliberately override certain bean definitions via an extra XML file.<br/> *<br/> * &lt;p&gt;&lt;b&gt;For a WebApplicationContext that reads in a different bean definition format,<br/> * create an analogous subclass of {</span><span style="color: #808080;">@link</span><span style="color: #008000;"> AbstractRefreshableWebApplicationContext}.&lt;/b&gt;<br/> * Such a context implementation can be specified as "contextClass" context-param<br/> * for ContextLoader or "contextClass" init-param for FrameworkServlet.<br/> </span><span style="color: #008000;">*/</span></div><p>&nbsp;</p><p>1、WebApplicationContext的实现类将根据XmlBeanDefinitionReader获取到bean的配置信息。</p><p>2、bean配置的来源有两个, 这两个位置配置的Bean都将被XmlBeanDefinitionReader理解并使用BeanFactory创建:</p><p>&nbsp;&nbsp;&nbsp; 1)上面说的contextConfigLocation,</p><p>&nbsp;&nbsp;&nbsp; 2)DispatcherServlet中配置的/WEB-INF/*-servlet.xml</p><p>web.xml中为DispatcherServler中设置的配置文件位置的方式是:</p><p>&lt;servlet&gt;</p><p>&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;test&lt;/servlet&gt;</p><p>&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet &lt;/servlet-class&gt;</p><p>&nbsp;&nbsp;&nbsp; &lt;init-param&gt;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;/WEB-INF/spring/*-servlet.xml&lt;/param-value&gt;</p><p>&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;</p><p>&lt;/servlet&gt;</p><p>&nbsp;</p><p>这里的配置方式与&lt;context-param&gt;中的配置方式类似。</p><p>如果不指定,默认的上就是/WEB-INF/*-servlet.xml 。例如上面的使用test作为servlet-name,也就是说namespace是test,如果不配置,默认设置就是/WEB-INF/test-servlet.xml&nbsp;</p><p>&nbsp;</p><p>根据XmlWebApplicationContext的与配置相关的类图:</p><p>&nbsp;<img src="http://images.cnitblog.com/i/512650/201407/260823385573039.x-png" alt="" /></p><p>&nbsp;</p><p>从上面可以看出,XmlWebApplication,实现了ConfigurableWebApplicationContext接口,这个接口中提供了关于ServletConfig,ServletContext,ConfigLocations,Namespace的操作,并且继承了WebApplicationContext ,而这些操作都是必要的,所以自定义的WebApplicationContext,也得实现ConfigurableWebApplicationContext接口才行。</p><p>&nbsp;</p><p>refresh:</p><p>在AbstractApplicationContext类中,实现了refresh:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> refresh() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> BeansException, IllegalStateException {<br/><br/> </span><span style="color: #0000ff;">synchronized</span> (<span style="color: #0000ff;">this</span><span style="color: #000000;">.startupShutdownMonitor) {<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Prepare this context for refreshing.</span><br/><span style="color: #000000;"><br/> prepareRefresh();<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Tell the subclass to refresh the internal bean factory.</span><br/><span style="color: #000000;"><br/> ConfigurableListableBeanFactory beanFactory </span>=<span style="color: #000000;"> obtainFreshBeanFactory();<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Prepare the bean factory for use in this context.</span><br/><span style="color: #000000;"><br/> prepareBeanFactory(beanFactory);<br/><br/> <br/><br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Allows post-processing of the bean factory in context subclasses.</span><br/><span style="color: #000000;"><br/> postProcessBeanFactory(beanFactory);<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Invoke factory processors registered as beans in the context.</span><br/><span style="color: #000000;"><br/> invokeBeanFactoryPostProcessors(beanFactory);<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Register bean processors that intercept bean creation.</span><br/><span style="color: #000000;"><br/> registerBeanPostProcessors(beanFactory);<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Initialize message source for this context.</span><br/><span style="color: #000000;"><br/> initMessageSource();<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Initialize event multicaster for this context.</span><br/><span style="color: #000000;"><br/> initApplicationEventMulticaster();<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Initialize other special beans in specific context subclasses.</span><br/><span style="color: #000000;"><br/> onRefresh();<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Check for listener beans and register them.</span><br/><span style="color: #000000;"><br/> registerListeners();<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Instantiate all remaining (non-lazy-init) singletons.</span><br/><span style="color: #000000;"><br/> finishBeanFactoryInitialization(beanFactory);<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Last step: publish corresponding event.</span><br/><span style="color: #000000;"><br/> finishRefresh();<br/><br/> }<br/><br/> <br/><br/> </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (BeansException ex) {<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Destroy already created singletons to avoid dangling resources.</span><br/><span style="color: #000000;"><br/> destroyBeans();<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Reset 'active' flag.</span><br/><span style="color: #000000;"><br/> cancelRefresh(ex);<br/><br/> <br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Propagate exception to caller.</span><br/><br/> <span style="color: #0000ff;">throw</span><span style="color: #000000;"> ex;<br/><br/> }<br/><br/> }<br/><br/> }</span></div><p>&nbsp;</p><p>&nbsp;</p><p>这个过程要处理的事情很多,不是现在就能看懂的,所以先把这个问题放一边去,以后再看。</p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3869552" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/f1194361820/p/3869552.html" target="_blank">Spring源码阅读:Spring WebApplicationContext初始化与消亡</a>,转载请注明。</p>http://www.cnblogs.com/YEKEYISHUO/p/3869281.htmlChrome和Firefox浏览器执行new Date() 函数传参数得到不同结果的陷阱 - YEKEYISHUO某日,同事问到关于new Date() 函数传参数,在火狐浏览器和谷歌浏览器控制台运行,会得到不同的结果,刚开始觉得不可能,后来实际操作才发现此陷阱var date = new Date('2014-07-25T23:00:00');alert(date);在火狐浏览器返回的是:Date {Fri ...2014-07-25T17:24:00Z2014-07-25T17:24:00ZYEKEYISHUOhttp://www.cnblogs.com/YEKEYISHUO/<p>某日,同事问到关于new Date() 函数传参数,在火狐浏览器和谷歌浏览器控制台运行,会得到不同的结果,刚开始觉得不可能,后来实际操作才发现此陷阱</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">var</span> date = <span style="color: #0000ff;">new</span> Date('2014-07-25T23:00:00'<span style="color: #000000;">);<br/>alert(date);</span></div><p>在火狐浏览器返回的是:</p><p>Date {Fri Jul 25 2014 23:00:00 GMT+0800}</p><p>火狐浏览器版本(通过navigator.userAgent输出):"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0"</p><p>在谷歌浏览器返回的是:</p><p>Sat Jul 26 2014 07:00:00 GMT+0800 (中国标准时间)</p><p>谷歌浏览器版本(通过navigator.userAgent输出):"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"</p><p>两个时间对比,谷歌浏览器把传进的字符串当做是UTC时间,加上了8个小时(北京处于东八区),new Date()内部调用的是Date.parse('2014-07-25T23:00:00Z')函数</p><p>而火狐浏览器当做是本地时区没有自动加上,在火狐浏览器中传递UTC格式字符串最后加上Z(Z表示zulu time,就是格林威治时间)。</p><p>当然也可以在UTC字符串末尾加入一个零时区的offset&ldquo;+00:00&rdquo;,如&lsquo;2014-07-25T23:00:00+00:00&rsquo;。</p><p>火狐浏览器运行结果如下:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">new</span> Date('2014-07-25T23:00:00'<span style="color: #000000;">);<br/>Date {Fri Jul </span>25 2014 23:00:00 GMT+0800<span style="color: #000000;">}<br/></span><span style="color: #0000ff;">new</span> Date('2014-07-25T23:00:00Z'<span style="color: #000000;">);<br/>Date {Sat Jul </span>26 2014 07:00:00 GMT+0800<span style="color: #000000;">}<br/></span><span style="color: #0000ff;">new</span> Date('2014-07-25T23:00:00+00:00'<span style="color: #000000;">);<br/>Date {Sat Jul </span>26 2014 07:00:00 GMT+0800}</div><p>谷歌浏览器运行结果如下:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">new</span> Date('2014-07-25T23:00:00'<span style="color: #000000;">);<br/>Sat Jul </span>26 2014 07:00:00 GMT+0800<span style="color: #000000;"> (中国标准时间)<br/></span><span style="color: #0000ff;">new</span> Date('2014-07-25T23:00:00Z'<span style="color: #000000;">);<br/>Sat Jul </span>26 2014 07:00:00 GMT+0800<span style="color: #000000;"> (中国标准时间)<br/></span><span style="color: #0000ff;">new</span> Date('2014-07-25T23:00:00+00:00'<span style="color: #000000;">);<br/>Sat Jul </span>26 2014 07:00:00 GMT+0800 (中国标准时间)</div><p>因为不知道浏览器加不加区时,所以建议是自己写一个函数实现将字符串转化为时间格式:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008000;">//</span><span style="color: #008000;">将字符串转换为时间格式,适用各种浏览器,格式如2011-08-03 09:15:11</span><br/><span style="color: #0000ff;">function</span><span style="color: #000000;"> GetTimeByTimeStr(dateString) {<br/></span><span style="color: #0000ff;">var</span> timeArr=dateStr.split(" "<span style="color: #000000;">);<br/></span><span style="color: #0000ff;">var</span> d=timeArr[0].split("-"<span style="color: #000000;">);<br/></span><span style="color: #0000ff;">var</span> t=timeArr[1].split(":"<span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">new</span> Date(d[0],(d[1]-1),d[2],t[0],t[1],t[2<span style="color: #000000;">]); <br/>}<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;">将时间转换为字符串格式,适用各种浏览器</span><br/><span style="color: #0000ff;">function</span><span style="color: #000000;"> GetTimeStrByTime(time,stringType) { <br/> </span><span style="color: #0000ff;">var</span> y =<span style="color: #000000;"> time.getFullYear();<br/> </span><span style="color: #0000ff;">var</span> M = time.getMonth() + 1<span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">var</span> d =<span style="color: #000000;"> time.getDate();<br/> </span><span style="color: #0000ff;">var</span> h =<span style="color: #000000;"> time.getHours();<br/> </span><span style="color: #0000ff;">var</span> m =<span style="color: #000000;"> date.getMinutes();<br/> </span><span style="color: #0000ff;">if</span>(stringType==1<span style="color: #000000;">)<br/> </span><span style="color: #0000ff;">return</span> y + '-' + (M &lt; 10 ? ('0' + M) : M) + '-' + (d &lt; 10 ? ('0' + d) : d) + " " + (h &lt; 10 ? ('0' + h) : h) + ":" + (m &lt; 10 ? ('0' +<span style="color: #000000;"> m) : m);<br/> </span><span style="color: #0000ff;">return</span> y + '/' + (M &lt; 10 ? ('0' + M) : M) + '/' + (d &lt; 10 ? ('0' + d) : d) + " " + (h &lt; 10 ? ('0' + h) : h) + ":" + (m &lt; 10 ? ('0' +<span style="color: #000000;"> m) : m);<br/>}</span></div><p>另外,可以对常见的JSON格式数据进行扩展转换</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008000;">//</span><span style="color: #008000;">将json格式时间字符串规范化为正规字符串或者时间,如<span style="font-family: Courier New;">"\/Date(1406217600000)\/" </span></span><br /><span style="color: #0000ff;">function</span><span style="color: #000000;"> GetTimeStrByJsonStr(JsonStr) {<br/> </span><span style="color: #0000ff;">var</span> date = <span style="color: #0000ff;">new</span> Date(parseInt(sonStr.replace("/Date(", "").replace(")/", ""), 10<span style="color: #000000;">));<br/> </span><span style="color: #0000ff;">return</span> GetTimeStrByTime(date,2<span style="color: #000000;">);<br/>}<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">时间参数为&ldquo;7月25日13时&rdquo;</span><br/><span style="color: #0000ff;">function</span><span style="color: #000000;"> getDateTimeStr(startDate,dateString) {<br/> </span><span style="color: #0000ff;">var</span> currenthour = dateString.split('日')[1<span style="color: #000000;">];<br/> </span><span style="color: #0000ff;">if</span> (currenthour.indexOf("时") != -1<span style="color: #000000;">)<br/> currenthour </span>= currenthour.split('时')[0<span style="color: #000000;">];<br/> </span><span style="color: #0000ff;">if</span> (currenthour == 0<span style="color: #000000;">)<br/> currenthour </span>= 24<span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">var</span> tempdate = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());<br/> tempdate.setTime(tempdate.getTime() </span>+ currenthour * 3600000<span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">return</span> GetTimeStrByTime(tempdate, 2<span style="color: #000000;">);<br/>}</span></div><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3869281" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/YEKEYISHUO/p/3869281.html" target="_blank">Chrome和Firefox浏览器执行new Date() 函数传参数得到不同结果的陷阱</a>,转载请注明。</p>http://www.cnblogs.com/lihao123/p/3869159.html一步一步实现基于Task的Promise库(二)all和any方法的设计和实现 - lh2907883在上一篇中我们已经初步完成了Task类,如果仅仅是这些,那么没有多大意义,因为网上这类js库有很多,现在我们来些更复杂的使用场景。如果我们现在有这样一个需求:我们要先读取aa.txt的内容,然后去后台解析,同时bb.txt也要读取解析,然后当两个文件都解析完了,我们还要合并两部分内容存到cc.txt...2014-07-25T16:52:00Z2014-07-25T16:52:00Zlh2907883http://www.cnblogs.com/lihao123/<p>在<a title="一步一步实现基于Task的Promise库(一)Promise的基本实现" href="http://www.cnblogs.com/lihao123/p/3869105.html" target="_blank">上一篇</a>中我们已经初步完成了Task类,如果仅仅是这些,那么没有多大意义,因为网上这类js库有很多,现在我们来些更复杂的使用场景。</p><p>如果我们现在有这样一个需求:我们要先读取aa.txt的内容,然后去后台解析,同时bb.txt也要读取解析,然后当两个文件都解析完了,我们还要合并两部分内容存到cc.txt中,最后发个通知说ok了。。需求很变态,但是我还是想问有没有好的办法呢?按照最原始的嵌套回调的写法好像不是那么容易了,因为你没法知道aa.txt和bb.txt两个文件的读取解析谁先完成,所以你除了要关注逻辑本身还得花费一些功夫在这个谁先谁后上面,如果需求变了。。。然后就没有然后了,想想我就要吐血。</p><p>那么回到上一章的Task类,Task有没有办法解决这个问题呢?回答是有,先看下面的代码:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">1</span> <span style="color: #0000ff;">var</span> taskExp_1 = <span style="color: #0000ff;">new</span> Task(readFile, [<span style="color: #800000;">"</span><span style="color: #800000;">aa.txt</span><span style="color: #800000;">"</span>]).then(resolveFile, [<span style="color: #800000;">"</span><span style="color: #800000;">/service/fileResolve.ashx?file=aa.txt</span><span style="color: #800000;">"</span><span style="color: #000000;">]);<br/></span><span style="color: #008080;">2</span> <span style="color: #0000ff;">var</span> taskExp_2 = <span style="color: #0000ff;">new</span> Task(readFile, [<span style="color: #800000;">"</span><span style="color: #800000;">bb.txt</span><span style="color: #800000;">"</span>]).then(resolveFile, [<span style="color: #800000;">"</span><span style="color: #800000;">/service/fileResolve.ashx?file=bb.txt</span><span style="color: #800000;">"</span><span style="color: #000000;">]);<br/></span><span style="color: #008080;">3</span> <span style="color: #0000ff;">var</span> taskExp_3 = <span style="color: #0000ff;">new</span> Task(taskExp_1, taskExp_2).all(writeFile, [<span style="color: #800000;">"</span><span style="color: #800000;">cc.txt</span><span style="color: #800000;">"</span>]).then(sendMail).start();</div><p>如同需求描述的一样,taskExp_1,taskExp_2分别描述了aa.txt和bb.txt的读取和解析,taskExp_3的构造方法里面包括了taskExp_1,taskExp_2,后面的all方法表示需要taskExp_1和taskExp_2都完成才能执行writeFile,最后才是sendMail。这样一来彻底解决了这类需求带来的复杂性,如果把all改成any表示taskExp_1和taskExp_2完成其中一个就能执行writeFile。</p><p>在实现all和any方法之前,先看一看我们将要面临哪些问题:</p><ol><li>现在new Task(),then(),all(),any()方法的形参可以是多个异步操作了,并且每个异步操作可以是一个方法和它的参数,也可以是一个Task。</li><li>既然这些方法的形参可以是Task,那么我们理所当然要支持Task的完成通知。</li><li>一组异步操作的返回值如何传递到下一组异步操作 ,对于all方法如何接收前一组异步操作的所有输出参数呢?在上一章里我们通过this.param接收参数,这里对于then,any方法同样如此,因为最终它们只会有一个异步操作的输出参数传递到下一个异步操作,all方法比较特殊,我斟酌好久决定使用this.param[0],this.param[1]... 来接收同组的不同异步操作的输出参数</li><li>当不同状态的Task作为参数传递到另一个Task中时(未开始执行的,正在执行的,执行完成的),应该怎么处理?我们还得支持Task的状态管理。</li></ol><p>继续上一章所写的Task类来扩展这两个方法,现在我们以一个标准的js库形式来书写实现细节,这个库命名为Task.js:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('e2ea5e58-82ce-4d43-9c4b-09425acc8ff6')"><div id="cnblogs_code_open_e2ea5e58-82ce-4d43-9c4b-09425acc8ff6" class="cnblogs_code_hide"><span style="color: #008080;"> 1</span> (<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">var</span> isFunction = <span style="color: #0000ff;">function</span><span style="color: #000000;">(target){<br/></span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">return</span> target <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Function;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">var</span> isArray = <span style="color: #0000ff;">function</span><span style="color: #000000;">(target){<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">return</span> target <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Array;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 8</span> <br/><span style="color: #008080;"> 9</span> <span style="color: #008000;">//</span><span style="color: #008000;">自定义事件管理(代码摘抄自http://www.cnblogs.com/dolphinX/p/3254017.html)</span><br/><span style="color: #008080;"> 10</span> <span style="color: #0000ff;">var</span> EventManager = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 11</span> <span style="color: #0000ff;">this</span>.handlers =<span style="color: #000000;"> {};<br/></span><span style="color: #008080;"> 12</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 13</span> EventManager.prototype =<span style="color: #000000;"> {<br/></span><span style="color: #008080;"> 14</span> <span style="color: #000000;"> constructor: EventManager,<br/></span><span style="color: #008080;"> 15</span> addHandler: <span style="color: #0000ff;">function</span><span style="color: #000000;">(type, handler){<br/></span><span style="color: #008080;"> 16</span> <span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">typeof</span> <span style="color: #0000ff;">this</span>.handlers[type] == 'undefined'<span style="color: #000000;">){<br/></span><span style="color: #008080;"> 17</span> <span style="color: #0000ff;">this</span>.handlers[type] = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Array();<br/></span><span style="color: #008080;"> 18</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 19</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">.handlers[type].push(handler);<br/></span><span style="color: #008080;"> 20</span> <span style="color: #000000;"> },<br/></span><span style="color: #008080;"> 21</span> removeHandler: <span style="color: #0000ff;">function</span><span style="color: #000000;">(type, handler){<br/></span><span style="color: #008080;"> 22</span> <span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">this</span>.handlers[type] <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Array){<br/></span><span style="color: #008080;"> 23</span> <span style="color: #0000ff;">var</span> handlers = <span style="color: #0000ff;">this</span><span style="color: #000000;">.handlers[type];<br/></span><span style="color: #008080;"> 24</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;handlers.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;"> 25</span> <span style="color: #0000ff;">if</span>(handler[i] ==<span style="color: #000000;"> handler){<br/></span><span style="color: #008080;"> 26</span> handlers.splice(i, 1<span style="color: #000000;">);<br/></span><span style="color: #008080;"> 27</span> <span style="color: #0000ff;">break</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 28</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 29</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 30</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 31</span> <span style="color: #000000;"> },<br/></span><span style="color: #008080;"> 32</span> trigger: <span style="color: #0000ff;">function</span><span style="color: #000000;">(type, event){<br/></span><span style="color: #008080;"> 33</span> <span style="color: #008000;">/*</span><br/><span style="color: #008080;"> 34</span> <span style="color: #008000;"> if(!event.target){<br/></span><span style="color: #008080;"> 35</span> <span style="color: #008000;"> event.target = this;<br/></span><span style="color: #008080;"> 36</span> <span style="color: #008000;"> }<br/></span><span style="color: #008080;"> 37</span> <span style="color: #008000;">*/</span><br/><span style="color: #008080;"> 38</span> <span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">this</span>.handlers[type] <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Array){<br/></span><span style="color: #008080;"> 39</span> <span style="color: #0000ff;">var</span> handlers = <span style="color: #0000ff;">this</span><span style="color: #000000;">.handlers[type];<br/></span><span style="color: #008080;"> 40</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;handlers.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;"> 41</span> <span style="color: #000000;"> handlers[i](event);<br/></span><span style="color: #008080;"> 42</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 43</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 44</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 45</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 46</span> <br/><span style="color: #008080;"> 47</span> <span style="color: #008000;">//</span><span style="color: #008000;">WorkItem的参数和Task一样,有下面几种形式,不过最终存到subItems里面的元素只有两种类型.一种是方法和它的参数,一种是Task对象</span><br/><span style="color: #008080;"> 48</span> <span style="color: #008000;">//</span><span style="color: #008000;">1.(func, [funcArg1, funcArg2])</span><br/><span style="color: #008080;"> 49</span> <span style="color: #008000;">//</span><span style="color: #008000;">2.(func, funcArg1, funcArg2, ....)</span><br/><span style="color: #008080;"> 50</span> <span style="color: #008000;">//</span><span style="color: #008000;">3.(task1, task2, ....)</span><br/><span style="color: #008080;"> 51</span> <span style="color: #008000;">//</span><span style="color: #008000;">4.([func, funcArg1, funcArg2, ....]</span><br/><span style="color: #008080;"> 52</span> <span style="color: #008000;">//</span><span style="color: #008000;"> ,[func, [funcArg1, funcArg2]]</span><br/><span style="color: #008080;"> 53</span> <span style="color: #008000;">//</span><span style="color: #008000;"> ,task1</span><br/><span style="color: #008080;"> 54</span> <span style="color: #008000;">//</span><span style="color: #008000;"> , ....</span><br/><span style="color: #008080;"> 55</span> <span style="color: #008000;">//</span><span style="color: #008000;"> )</span><br/><span style="color: #008080;"> 56</span> <span style="color: #0000ff;">var</span> WorkItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(arrayArgs){<br/></span><span style="color: #008080;"> 57</span> <span style="color: #008000;">//</span><span style="color: #008000;">WorkItem其实是一组异步操作的集合,_subItems就是这个集合</span><br/><span style="color: #008080;"> 58</span> <span style="color: #0000ff;">var</span> _subItems =<span style="color: #000000;"> [];<br/></span><span style="color: #008080;"> 59</span> <span style="color: #0000ff;">var</span> _checkFunc = <span style="color: #0000ff;">function</span><span style="color: #000000;">(args){<br/></span><span style="color: #008080;"> 60</span> <span style="color: #0000ff;">if</span>(isFunction(args[0<span style="color: #000000;">])){<br/></span><span style="color: #008080;"> 61</span> <span style="color: #0000ff;">if</span>(args.length == 2 &amp;&amp; isArray(args[1<span style="color: #000000;">])){<br/></span><span style="color: #008080;"> 62</span> _subItems.push({'isFunc': <span style="color: #0000ff;">true</span>, 'func': args[0], 'args': args[1<span style="color: #000000;">]});<br/></span><span style="color: #008080;"> 63</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 64</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;"> 65</span> _subItems.push({'isFunc': <span style="color: #0000ff;">true</span>, 'func': args[0], 'args': args.slice(1<span style="color: #000000;">)});<br/></span><span style="color: #008080;"> 66</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 67</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 68</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 69</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 70</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 71</span> <span style="color: #0000ff;">var</span> _checkTask = <span style="color: #0000ff;">function</span><span style="color: #000000;">(task){<br/></span><span style="color: #008080;"> 72</span> <span style="color: #0000ff;">if</span>(task <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Task){<br/></span><span style="color: #008080;"> 73</span> _subItems.push({'isFunc': <span style="color: #0000ff;">false</span>, 'task'<span style="color: #000000;">: task});<br/></span><span style="color: #008080;"> 74</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 75</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 76</span> <span style="color: #008000;">//</span><span style="color: #008000;">这里是对形参的检测,看看是否满足上面的4种形式</span><br/><span style="color: #008080;"> 77</span> <span style="color: #0000ff;">if</span>(!<span style="color: #000000;">_checkFunc(arrayArgs)){<br/></span><span style="color: #008080;"> 78</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;arrayArgs.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;"> 79</span> <span style="color: #0000ff;">if</span>(!<span style="color: #000000;">_checkFunc(arrayArgs[i])){<br/></span><span style="color: #008080;"> 80</span> <span style="color: #000000;"> _checkTask(arrayArgs[i]);<br/></span><span style="color: #008080;"> 81</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 82</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 83</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 84</span> <br/><span style="color: #008080;"> 85</span> <span style="color: #008000;">//</span><span style="color: #008000;">开始执行SubItem</span><br/><span style="color: #008080;"> 86</span> <span style="color: #0000ff;">var</span> _startSubItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(subItemIndex, context){<br/></span><span style="color: #008080;"> 87</span> <span style="color: #0000ff;">var</span> subItem =<span style="color: #000000;"> _subItems[subItemIndex];<br/></span><span style="color: #008080;"> 88</span> <span style="color: #008000;">//</span><span style="color: #008000;">如果subItem是方法和它的参数</span><br/><span style="color: #008080;"> 89</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(subItem.isFunc){<br/></span><span style="color: #008080;"> 90</span> <span style="color: #008000;">//</span><span style="color: #008000;">先获取方法的上下文环境(就是方法里面的this)</span><br/><span style="color: #008080;"> 91</span> <span style="color: #0000ff;">var</span> workItemCxt =<span style="color: #000000;"> context.getWorkItemContext(subItemIndex);<br/></span><span style="color: #008080;"> 92</span> <span style="color: #008000;">//</span><span style="color: #008000;">再执行方法</span><br/><span style="color: #008080;"> 93</span> <span style="color: #000000;"> subItem.func.apply(workItemCxt, subItem.args);<br/></span><span style="color: #008080;"> 94</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 95</span> <span style="color: #008000;">//</span><span style="color: #008000;">如果subItem是Task对象</span><br/><span style="color: #008080;"> 96</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;"> 97</span> <span style="color: #008000;">//</span><span style="color: #008000;">如果task已经完成</span><br/><span style="color: #008080;"> 98</span> <span style="color: #0000ff;">if</span>(subItem.task.getStatus() ==<span style="color: #000000;"> TaskStatus.finished){<br/></span><span style="color: #008080;"> 99</span> <span style="color: #000000;"> context.end(subItem.task.getOutput(), subItemIndex)<br/></span><span style="color: #008080;">100</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">101</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">102</span> <span style="color: #008000;">//</span><span style="color: #008000;">先注册Task对象的完成事件</span><br/><span style="color: #008080;">103</span> subItem.task.finished(<span style="color: #0000ff;">function</span><span style="color: #000000;">(output){<br/></span><span style="color: #008080;">104</span> <span style="color: #000000;"> context.end(output, subItemIndex);<br/></span><span style="color: #008080;">105</span> <span style="color: #000000;"> });<br/></span><span style="color: #008080;">106</span> <span style="color: #008000;">//</span><span style="color: #008000;">再启动这个task</span><br/><span style="color: #008080;">107</span> <span style="color: #000000;"> subItem.task.start(context.inputParams);<br/></span><span style="color: #008080;">108</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">109</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">110</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">111</span> <span style="color: #0000ff;">this</span>.condition = ""<span style="color: #000000;">;<br/></span><span style="color: #008080;">112</span> <span style="color: #008000;">//</span><span style="color: #008000;">开始执行WorkItem</span><br/><span style="color: #008080;">113</span> <span style="color: #0000ff;">this</span>.start = <span style="color: #0000ff;">function</span><span style="color: #000000;">(context){<br/></span><span style="color: #008080;">114</span> <span style="color: #000000;"> context.setItemsCount(_subItems.length);<br/></span><span style="color: #008080;">115</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;_subItems.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">116</span> <span style="color: #000000;"> _startSubItem(i, context);<br/></span><span style="color: #008080;">117</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">118</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">119</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">120</span> <br/><span style="color: #008080;">121</span> <span style="color: #008000;">//</span><span style="color: #008000;">异步操作上下文</span><br/><span style="color: #008080;">122</span> <span style="color: #0000ff;">var</span> Context = <span style="color: #0000ff;">function</span><span style="color: #000000;">(endCallback, inputParams){<br/></span><span style="color: #008080;">123</span> <span style="color: #0000ff;">var</span> _this = <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">124</span> <span style="color: #008000;">//</span><span style="color: #008000;">Workitem里面的每一个Item会按各自的索引把返回值存到_rawOutputParams里,这样做的目的是为了方便后续操作的先决条件判断</span><br/><span style="color: #008080;">125</span> <span style="color: #0000ff;">var</span> _rawOutputParams =<span style="color: #000000;"> [];<br/></span><span style="color: #008080;">126</span> <span style="color: #008000;">//</span><span style="color: #008000;">子Item个数</span><br/><span style="color: #008080;">127</span> <span style="color: #0000ff;">var</span><span style="color: #000000;"> _itemCount;<br/></span><span style="color: #008080;">128</span> <span style="color: #008000;">//</span><span style="color: #008000;">先决条件的判断方法集合,判断的同时也会更新outputParams</span><br/><span style="color: #008080;">129</span> <span style="color: #0000ff;">var</span> _condition =<span style="color: #000000;"> {<br/></span><span style="color: #008080;">130</span> then: <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">131</span> _this.outputParams = _rawOutputParams[0<span style="color: #000000;">].value;<br/></span><span style="color: #008080;">132</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">133</span> <span style="color: #000000;"> },<br/></span><span style="color: #008080;">134</span> all: <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">135</span> _this.outputParams =<span style="color: #000000;"> [];<br/></span><span style="color: #008080;">136</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;_itemCount; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">137</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(_rawOutputParams[i]){<br/></span><span style="color: #008080;">138</span> _this.outputParams[i] =<span style="color: #000000;"> _rawOutputParams[i].value;<br/></span><span style="color: #008080;">139</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">140</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">141</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">142</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">143</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">144</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">145</span> <span style="color: #000000;"> },<br/></span><span style="color: #008080;">146</span> any: <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">147</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;_itemCount; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">148</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(_rawOutputParams[i]){<br/></span><span style="color: #008080;">149</span> _this.outputParams =<span style="color: #000000;"> _rawOutputParams[i].value;<br/></span><span style="color: #008080;">150</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">151</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">152</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">153</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">154</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">155</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">156</span> <br/><span style="color: #008080;">157</span> <span style="color: #008000;">//</span><span style="color: #008000;">异步操作的输入操作</span><br/><span style="color: #008080;">158</span> <span style="color: #0000ff;">this</span>.inputParams =<span style="color: #000000;"> inputParams;<br/></span><span style="color: #008080;">159</span> <span style="color: #008000;">//</span><span style="color: #008000;">最终异步操作上下文结束时的输出参数(一般是一个操作的输出参数,all条件的输出参数比较特殊,是一个数组,每一个元素对应每一个子Workitem的输出参数)</span><br/><span style="color: #008080;">160</span> <span style="color: #0000ff;">this</span>.outputParams = <span style="color: #0000ff;">null</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">161</span> <span style="color: #0000ff;">this</span>.setItemsCount = <span style="color: #0000ff;">function</span><span style="color: #000000;">(itemCount){<br/></span><span style="color: #008080;">162</span> _itemCount =<span style="color: #000000;"> itemCount;<br/></span><span style="color: #008080;">163</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">164</span> <span style="color: #008000;">//</span><span style="color: #008000;">测试_rawOutputParams对于key条件是否通过</span><br/><span style="color: #008080;">165</span> <span style="color: #0000ff;">this</span>.testCondition = <span style="color: #0000ff;">function</span><span style="color: #000000;">(key){<br/></span><span style="color: #008080;">166</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> _condition[key]();<br/></span><span style="color: #008080;">167</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">168</span> <span style="color: #008000;">//</span><span style="color: #008000;">索引为index的子Workitem完成时会调用这个方法</span><br/><span style="color: #008080;">169</span> <span style="color: #0000ff;">this</span>.end = <span style="color: #0000ff;">function</span><span style="color: #000000;">(output, index){<br/></span><span style="color: #008080;">170</span> _rawOutputParams[index] =<span style="color: #000000;"> {<br/></span><span style="color: #008080;">171</span> <span style="color: #000000;"> value: output<br/></span><span style="color: #008080;">172</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">173</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(endCallback){<br/></span><span style="color: #008080;">174</span> <span style="color: #000000;"> endCallback(output);<br/></span><span style="color: #008080;">175</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">176</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">177</span> <span style="color: #008000;">//</span><span style="color: #008000;">生成一个子Workitem执行时的上下文环境</span><br/><span style="color: #008080;">178</span> <span style="color: #0000ff;">this</span>.getWorkItemContext = <span style="color: #0000ff;">function</span><span style="color: #000000;">(index){<br/></span><span style="color: #008080;">179</span> <span style="color: #008000;">//</span><span style="color: #008000;">这个是子Item的上下文对象(就是this)</span><br/><span style="color: #008080;">180</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> {<br/></span><span style="color: #008080;">181</span> <span style="color: #008000;">//</span><span style="color: #008000;">传递给上下文的参数</span><br/><span style="color: #008080;">182</span> <span style="color: #000000;"> param: _this.inputParams,<br/></span><span style="color: #008080;">183</span> <span style="color: #008000;">//</span><span style="color: #008000;">调用end方法告知异步操作的完成</span><br/><span style="color: #008080;">184</span> end: <span style="color: #0000ff;">function</span><span style="color: #000000;">(output){<br/></span><span style="color: #008080;">185</span> <span style="color: #000000;"> _this.end(output, index);<br/></span><span style="color: #008080;">186</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">187</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">188</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">189</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">190</span> <br/><span style="color: #008080;">191</span> <span style="color: #008000;">//</span><span style="color: #008000;">Task的状态</span><br/><span style="color: #008080;">192</span> <span style="color: #0000ff;">var</span> TaskStatus =<span style="color: #000000;"> {<br/></span><span style="color: #008080;">193</span> <span style="color: #008000;">//</span><span style="color: #008000;">未开始</span><br/><span style="color: #008080;">194</span> pending: 0<span style="color: #000000;">,<br/></span><span style="color: #008080;">195</span> <span style="color: #008000;">//</span><span style="color: #008000;">正在进行</span><br/><span style="color: #008080;">196</span> doing: 1<span style="color: #000000;">,<br/></span><span style="color: #008080;">197</span> <span style="color: #008000;">//</span><span style="color: #008000;">已完成</span><br/><span style="color: #008080;">198</span> finished: 2<br/><span style="color: #008080;">199</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">200</span> <br/><span style="color: #008080;">201</span> <span style="color: #008000;">//</span><span style="color: #008000;">不定义具体形参,直接使用arguments</span><br/><span style="color: #008080;">202</span> window.Task = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">203</span> <span style="color: #0000ff;">var</span> _status =<span style="color: #000000;"> TaskStatus.pending;<br/></span><span style="color: #008080;">204</span> <span style="color: #0000ff;">var</span> _wItemQueue =<span style="color: #000000;"> [], _currentItem, _currentContext;<br/></span><span style="color: #008080;">205</span> <span style="color: #0000ff;">var</span> _eventManager = <span style="color: #0000ff;">new</span><span style="color: #000000;"> EventManager();<br/></span><span style="color: #008080;">206</span> <span style="color: #0000ff;">var</span><span style="color: #000000;"> _output;<br/></span><span style="color: #008080;">207</span> <span style="color: #008000;">//</span><span style="color: #008000;">初始化一个WorkItem,并添加到执行队列中</span><br/><span style="color: #008080;">208</span> <span style="color: #0000ff;">var</span> _initWorkItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(args){<br/></span><span style="color: #008080;">209</span> <span style="color: #0000ff;">var</span> arrayArgs =<span style="color: #000000;"> [];<br/></span><span style="color: #008080;">210</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;args.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">211</span> arrayArgs[i] =<span style="color: #000000;"> args[i];<br/></span><span style="color: #008080;">212</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">213</span> <span style="color: #0000ff;">var</span> item = <span style="color: #0000ff;">new</span><span style="color: #000000;"> WorkItem(arrayArgs);<br/></span><span style="color: #008080;">214</span> <span style="color: #000000;"> _wItemQueue.push(item);<br/></span><span style="color: #008080;">215</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> item;<br/></span><span style="color: #008080;">216</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">217</span> <span style="color: #008000;">//</span><span style="color: #008000;">设置item的先决条件</span><br/><span style="color: #008080;">218</span> <span style="color: #0000ff;">var</span> _setItemCondition = <span style="color: #0000ff;">function</span><span style="color: #000000;">(item, condition){<br/></span><span style="color: #008080;">219</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(condition){<br/></span><span style="color: #008080;">220</span> item.condition =<span style="color: #000000;"> condition;<br/></span><span style="color: #008080;">221</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">222</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">223</span> <span style="color: #008000;">//</span><span style="color: #008000;">试着执行下一个异步操作,如果这个操作满足他的先决条件,那就执行;如果已经式最后一个异步操作了,就触发完成事件</span><br/><span style="color: #008080;">224</span> <span style="color: #0000ff;">var</span> _tryDoNextItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(output){<br/></span><span style="color: #008080;">225</span> <span style="color: #0000ff;">var</span> next =<span style="color: #000000;"> _getCurNextItem();<br/></span><span style="color: #008080;">226</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(next){<br/></span><span style="color: #008080;">227</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(_currentContext.testCondition(next.condition)){<br/></span><span style="color: #008080;">228</span> _currentItem =<span style="color: #000000;"> next;<br/></span><span style="color: #008080;">229</span> <span style="color: #000000;"> _doCurrentItem();<br/></span><span style="color: #008080;">230</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">231</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">232</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">233</span> _status =<span style="color: #000000;"> TaskStatus.finished;<br/></span><span style="color: #008080;">234</span> _output =<span style="color: #000000;"> output;<br/></span><span style="color: #008080;">235</span> _eventManager.trigger("finish"<span style="color: #000000;">, output);<br/></span><span style="color: #008080;">236</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">237</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">238</span> <span style="color: #008000;">//</span><span style="color: #008000;">执行当前的Workitem</span><br/><span style="color: #008080;">239</span> <span style="color: #0000ff;">var</span> _doCurrentItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(contextParam){<br/></span><span style="color: #008080;">240</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(contextParam) {<br/></span><span style="color: #008080;">241</span> _currentContext = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Context(_tryDoNextItem, contextParam);<br/></span><span style="color: #008080;">242</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">243</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">244</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(_currentContext){<br/></span><span style="color: #008080;">245</span> _currentContext = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Context(_tryDoNextItem, _currentContext.outputParams);<br/></span><span style="color: #008080;">246</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">247</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">248</span> _currentContext = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Context(_tryDoNextItem);<br/></span><span style="color: #008080;">249</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">250</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">251</span> <span style="color: #000000;"> _currentItem.start(_currentContext);<br/></span><span style="color: #008080;">252</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">253</span> <span style="color: #008000;">//</span><span style="color: #008000;">获取下一个异步操作,如果已经是最后一个了返回undefined</span><br/><span style="color: #008080;">254</span> <span style="color: #0000ff;">var</span> _getCurNextItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">255</span> <span style="color: #0000ff;">var</span> i=0<span style="color: #000000;">;<br/></span><span style="color: #008080;">256</span> <span style="color: #0000ff;">for</span>(; i&lt;_wItemQueue.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">257</span> <span style="color: #0000ff;">if</span>(_currentItem ==<span style="color: #000000;"> _wItemQueue[i]){<br/></span><span style="color: #008080;">258</span> <span style="color: #0000ff;">break</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">259</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">260</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">261</span> <span style="color: #0000ff;">return</span> _wItemQueue[i + 1<span style="color: #000000;">];<br/></span><span style="color: #008080;">262</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">263</span> _currentItem =<span style="color: #000000;"> _initWorkItem(arguments);<br/></span><span style="color: #008080;">264</span> <br/><span style="color: #008080;">265</span> <span style="color: #008000;">//</span><span style="color: #008000;">获取Task当前状态</span><br/><span style="color: #008080;">266</span> <span style="color: #0000ff;">this</span>.getStatus = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">267</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> _status;<br/></span><span style="color: #008080;">268</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">269</span> <span style="color: #008000;">//</span><span style="color: #008000;">获取Task完成时的输出参数</span><br/><span style="color: #008080;">270</span> <span style="color: #0000ff;">this</span>.getOutput = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">271</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> _output;<br/></span><span style="color: #008080;">272</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">273</span> <span style="color: #008000;">//</span><span style="color: #008000;">注册完成事件</span><br/><span style="color: #008080;">274</span> <span style="color: #0000ff;">this</span>.finished = <span style="color: #0000ff;">function</span><span style="color: #000000;">(callback){<br/></span><span style="color: #008080;">275</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(callback){<br/></span><span style="color: #008080;">276</span> _eventManager.addHandler("finish"<span style="color: #000000;">, callback);<br/></span><span style="color: #008080;">277</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">278</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">279</span> <span style="color: #008000;">//</span><span style="color: #008000;">任务开始(把do改成start是因为在ie下有问题,ie会把do当做保留字)</span><br/><span style="color: #008080;">280</span> <span style="color: #008000;">//</span><span style="color: #008000;">contextParam是一个上下文参数,可以在异步方法中通过this.Param引用</span><br/><span style="color: #008080;">281</span> <span style="color: #0000ff;">this</span>.start = <span style="color: #0000ff;">function</span><span style="color: #000000;">(contextParam){<br/></span><span style="color: #008080;">282</span> <span style="color: #0000ff;">if</span>(_status ==<span style="color: #000000;"> TaskStatus.pending){<br/></span><span style="color: #008080;">283</span> _status =<span style="color: #000000;"> TaskStatus.doing;<br/></span><span style="color: #008080;">284</span> <span style="color: #000000;"> _doCurrentItem(contextParam);<br/></span><span style="color: #008080;">285</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">286</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">287</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">288</span> <span style="color: #0000ff;">this</span>.then = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">289</span> <span style="color: #0000ff;">var</span> workItem =<span style="color: #000000;"> _initWorkItem(arguments);<br/></span><span style="color: #008080;">290</span> _setItemCondition(workItem, 'then'<span style="color: #000000;">);<br/></span><span style="color: #008080;">291</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">292</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">293</span> <span style="color: #0000ff;">this</span>.all = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">294</span> <span style="color: #0000ff;">var</span> workItem =<span style="color: #000000;"> _initWorkItem(arguments);<br/></span><span style="color: #008080;">295</span> _setItemCondition(workItem, 'all'<span style="color: #000000;">);<br/></span><span style="color: #008080;">296</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">297</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">298</span> <span style="color: #0000ff;">this</span>.any = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">299</span> <span style="color: #0000ff;">var</span> workItem =<span style="color: #000000;"> _initWorkItem(arguments);<br/></span><span style="color: #008080;">300</span> _setItemCondition(workItem, 'any'<span style="color: #000000;">);<br/></span><span style="color: #008080;">301</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">302</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">303</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">304</span> })();</div></div><p>除了之前的Task类之外,还添加了WorkItem类用来表示一组异步操作。代码有点多,细节请看注释。</p><p>最后给一个demo:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('bda6dfa9-3b72-4f63-8044-101a0a56b39d')"><div id="cnblogs_code_open_bda6dfa9-3b72-4f63-8044-101a0a56b39d" class="cnblogs_code_hide"><span style="color: #008080;"> 1</span> &lt;!DOCTYPE html&gt;<br/><span style="color: #008080;"> 2</span> &lt;html&gt;<br/><span style="color: #008080;"> 3</span> &lt;head&gt;<br/><span style="color: #008080;"> 4</span> &lt;title&gt;&lt;/title&gt;<br/><span style="color: #008080;"> 5</span> &lt;/head&gt;<br/><span style="color: #008080;"> 6</span> &lt;body&gt;<br/><span style="color: #008080;"> 7</span> &lt;script src="jquery-latest.js" type="text/javascript"&gt;&lt;/script&gt;<br/><span style="color: #008080;"> 8</span> &lt;script type="text/javascript"&gt;<br/><span style="color: #008080;"> 9</span> <span style="color: #008000;">//</span><span style="color: #008000;">promise</span><br/><span style="color: #008080;"> 10</span> <span style="color: #008000;">//</span><span style="color: #008000;">读取文件的原始内容</span><br/><span style="color: #008080;"> 11</span> <span style="color: #0000ff;">var</span> readFile = <span style="color: #0000ff;">function</span><span style="color: #000000;">(fileName){<br/></span><span style="color: #008080;"> 12</span> <span style="color: #0000ff;">var</span> _this = <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 13</span> window.setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 14</span> <span style="color: #0000ff;">var</span> rawContent = "xxxxxxxx (" + fileName + ")"<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 15</span> console.log("read '" + fileName + "' complete. rawContent is " +<span style="color: #000000;"> rawContent);<br/></span><span style="color: #008080;"> 16</span> <span style="color: #000000;"> _this.end(rawContent);<br/></span><span style="color: #008080;"> 17</span> }, 1000<span style="color: #000000;">);<br/></span><span style="color: #008080;"> 18</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 19</span> <span style="color: #008000;">//</span><span style="color: #008000;">请求服务器来解析原始内容,得到真正的内容</span><br/><span style="color: #008080;"> 20</span> <span style="color: #0000ff;">var</span> resolveFile = <span style="color: #0000ff;">function</span><span style="color: #000000;">(serverUrl){<br/></span><span style="color: #008080;"> 21</span> <span style="color: #0000ff;">var</span> _this = <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 22</span> <span style="color: #0000ff;">var</span> rawContent =<span style="color: #000000;"> _this.param;<br/></span><span style="color: #008080;"> 23</span> window.setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 24</span> <span style="color: #0000ff;">var</span> realContent = "Greeting (" + serverUrl + ")"<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 25</span> console.log("resolve file complete. realContent is " +<span style="color: #000000;"> realContent);<br/></span><span style="color: #008080;"> 26</span> <span style="color: #000000;"> _this.end(realContent);<br/></span><span style="color: #008080;"> 27</span> }, 1500<span style="color: #000000;">);<br/></span><span style="color: #008080;"> 28</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 29</span> <span style="color: #008000;">//</span><span style="color: #008000;">把真正的内容写入一开始的文件</span><br/><span style="color: #008080;"> 30</span> <span style="color: #0000ff;">var</span> writeFile = <span style="color: #0000ff;">function</span><span style="color: #000000;"> (fileName) {<br/></span><span style="color: #008080;"> 31</span> <span style="color: #0000ff;">var</span> _this = <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 32</span> window.setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 33</span> console.log("writeBack1 param[0] is " + _this.param[0] + " ;param[1] is " + _this.param[1<span style="color: #000000;">]);<br/></span><span style="color: #008080;"> 34</span> <span style="color: #000000;"> _this.end();<br/></span><span style="color: #008080;"> 35</span> }, 2000<span style="color: #000000;">);<br/></span><span style="color: #008080;"> 36</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 37</span> <span style="color: #0000ff;">var</span> sendMail = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 38</span> <span style="color: #0000ff;">var</span> _this = <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 39</span> window.setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 40</span> console.log("sendMail finished"<span style="color: #000000;">);<br/></span><span style="color: #008080;"> 41</span> <span style="color: #000000;"> _this.end();<br/></span><span style="color: #008080;"> 42</span> }, 1000<span style="color: #000000;">);<br/></span><span style="color: #008080;"> 43</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 44</span> <br/><span style="color: #008080;"> 45</span> <span style="color: #008000;">//</span><span style="color: #008000;">问题:</span><br/><span style="color: #008080;"> 46</span> <span style="color: #008000;">//</span><span style="color: #008000;">1.WorkItem的参数多样化 (一些没有意义的使用形式?)</span><br/><span style="color: #008080;"> 47</span> <span style="color: #008000;">//</span><span style="color: #008000;">2.new Task(),then,all,any方法参数可以接收Task对象 (Task完成的事件通知?)</span><br/><span style="color: #008080;"> 48</span> <span style="color: #008000;">//</span><span style="color: #008000;">3.一组异步操作的返回值如何传递到下一组异步操作 (对于all方法如何接收前一组异步操作的所有输出参数)</span><br/><span style="color: #008080;"> 49</span> <span style="color: #008000;">//</span><span style="color: #008000;">4.当不同状态的Task作为参数传递到另一个Task中时(未开始执行的,正在执行的,执行完成的),应该怎么处理 (Task状态管理)</span><br/><span style="color: #008080;"> 50</span> (<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 51</span> <span style="color: #0000ff;">var</span> isFunction = <span style="color: #0000ff;">function</span><span style="color: #000000;">(target){<br/></span><span style="color: #008080;"> 52</span> <span style="color: #0000ff;">return</span> target <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Function;<br/></span><span style="color: #008080;"> 53</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 54</span> <span style="color: #0000ff;">var</span> isArray = <span style="color: #0000ff;">function</span><span style="color: #000000;">(target){<br/></span><span style="color: #008080;"> 55</span> <span style="color: #0000ff;">return</span> target <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Array;<br/></span><span style="color: #008080;"> 56</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 57</span> <br/><span style="color: #008080;"> 58</span> <span style="color: #008000;">//</span><span style="color: #008000;">自定义事件管理(代码摘抄自http://www.cnblogs.com/dolphinX/p/3254017.html)</span><br/><span style="color: #008080;"> 59</span> <span style="color: #0000ff;">var</span> EventManager = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 60</span> <span style="color: #0000ff;">this</span>.handlers =<span style="color: #000000;"> {};<br/></span><span style="color: #008080;"> 61</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 62</span> EventManager.prototype =<span style="color: #000000;"> {<br/></span><span style="color: #008080;"> 63</span> <span style="color: #000000;"> constructor: EventManager,<br/></span><span style="color: #008080;"> 64</span> addHandler: <span style="color: #0000ff;">function</span><span style="color: #000000;">(type, handler){<br/></span><span style="color: #008080;"> 65</span> <span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">typeof</span> <span style="color: #0000ff;">this</span>.handlers[type] == 'undefined'<span style="color: #000000;">){<br/></span><span style="color: #008080;"> 66</span> <span style="color: #0000ff;">this</span>.handlers[type] = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Array();<br/></span><span style="color: #008080;"> 67</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 68</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">.handlers[type].push(handler);<br/></span><span style="color: #008080;"> 69</span> <span style="color: #000000;"> },<br/></span><span style="color: #008080;"> 70</span> removeHandler: <span style="color: #0000ff;">function</span><span style="color: #000000;">(type, handler){<br/></span><span style="color: #008080;"> 71</span> <span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">this</span>.handlers[type] <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Array){<br/></span><span style="color: #008080;"> 72</span> <span style="color: #0000ff;">var</span> handlers = <span style="color: #0000ff;">this</span><span style="color: #000000;">.handlers[type];<br/></span><span style="color: #008080;"> 73</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;handlers.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;"> 74</span> <span style="color: #0000ff;">if</span>(handler[i] ==<span style="color: #000000;"> handler){<br/></span><span style="color: #008080;"> 75</span> handlers.splice(i, 1<span style="color: #000000;">);<br/></span><span style="color: #008080;"> 76</span> <span style="color: #0000ff;">break</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 77</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 78</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 79</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 80</span> <span style="color: #000000;"> },<br/></span><span style="color: #008080;"> 81</span> trigger: <span style="color: #0000ff;">function</span><span style="color: #000000;">(type, event){<br/></span><span style="color: #008080;"> 82</span> <span style="color: #008000;">/*</span><br/><span style="color: #008080;"> 83</span> <span style="color: #008000;"> if(!event.target){<br/></span><span style="color: #008080;"> 84</span> <span style="color: #008000;"> event.target = this;<br/></span><span style="color: #008080;"> 85</span> <span style="color: #008000;"> }<br/></span><span style="color: #008080;"> 86</span> <span style="color: #008000;">*/</span><br/><span style="color: #008080;"> 87</span> <span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">this</span>.handlers[type] <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Array){<br/></span><span style="color: #008080;"> 88</span> <span style="color: #0000ff;">var</span> handlers = <span style="color: #0000ff;">this</span><span style="color: #000000;">.handlers[type];<br/></span><span style="color: #008080;"> 89</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;handlers.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;"> 90</span> <span style="color: #000000;"> handlers[i](event);<br/></span><span style="color: #008080;"> 91</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 92</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 93</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 94</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;"> 95</span> <br/><span style="color: #008080;"> 96</span> <span style="color: #008000;">//</span><span style="color: #008000;">WorkItem的参数和Task一样,有下面几种形式,不过最终存到subItems里面的元素只有两种类型.一种是方法和它的参数,一种是Task对象</span><br/><span style="color: #008080;"> 97</span> <span style="color: #008000;">//</span><span style="color: #008000;">1.(func, [funcArg1, funcArg2])</span><br/><span style="color: #008080;"> 98</span> <span style="color: #008000;">//</span><span style="color: #008000;">2.(func, funcArg1, funcArg2, ....)</span><br/><span style="color: #008080;"> 99</span> <span style="color: #008000;">//</span><span style="color: #008000;">3.(task1, task2, ....)</span><br/><span style="color: #008080;">100</span> <span style="color: #008000;">//</span><span style="color: #008000;">4.([func, funcArg1, funcArg2, ....]</span><br/><span style="color: #008080;">101</span> <span style="color: #008000;">//</span><span style="color: #008000;"> ,[func, [funcArg1, funcArg2]]</span><br/><span style="color: #008080;">102</span> <span style="color: #008000;">//</span><span style="color: #008000;"> ,task1</span><br/><span style="color: #008080;">103</span> <span style="color: #008000;">//</span><span style="color: #008000;"> , ....</span><br/><span style="color: #008080;">104</span> <span style="color: #008000;">//</span><span style="color: #008000;"> )</span><br/><span style="color: #008080;">105</span> <span style="color: #0000ff;">var</span> WorkItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(arrayArgs){<br/></span><span style="color: #008080;">106</span> <span style="color: #008000;">//</span><span style="color: #008000;">WorkItem其实是一组异步操作的集合,_subItems就是这个集合</span><br/><span style="color: #008080;">107</span> <span style="color: #0000ff;">var</span> _subItems =<span style="color: #000000;"> [];<br/></span><span style="color: #008080;">108</span> <span style="color: #0000ff;">var</span> _checkFunc = <span style="color: #0000ff;">function</span><span style="color: #000000;">(args){<br/></span><span style="color: #008080;">109</span> <span style="color: #0000ff;">if</span>(isFunction(args[0<span style="color: #000000;">])){<br/></span><span style="color: #008080;">110</span> <span style="color: #0000ff;">if</span>(args.length == 2 &amp;&amp; isArray(args[1<span style="color: #000000;">])){<br/></span><span style="color: #008080;">111</span> _subItems.push({'isFunc': <span style="color: #0000ff;">true</span>, 'func': args[0], 'args': args[1<span style="color: #000000;">]});<br/></span><span style="color: #008080;">112</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">113</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">114</span> _subItems.push({'isFunc': <span style="color: #0000ff;">true</span>, 'func': args[0], 'args': args.slice(1<span style="color: #000000;">)});<br/></span><span style="color: #008080;">115</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">116</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">117</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">118</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">119</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">120</span> <span style="color: #0000ff;">var</span> _checkTask = <span style="color: #0000ff;">function</span><span style="color: #000000;">(task){<br/></span><span style="color: #008080;">121</span> <span style="color: #0000ff;">if</span>(task <span style="color: #0000ff;">instanceof</span><span style="color: #000000;"> Task){<br/></span><span style="color: #008080;">122</span> _subItems.push({'isFunc': <span style="color: #0000ff;">false</span>, 'task'<span style="color: #000000;">: task});<br/></span><span style="color: #008080;">123</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">124</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">125</span> <span style="color: #008000;">//</span><span style="color: #008000;">这里是对形参的检测,看看是否满足上面的4种形式</span><br/><span style="color: #008080;">126</span> <span style="color: #0000ff;">if</span>(!<span style="color: #000000;">_checkFunc(arrayArgs)){<br/></span><span style="color: #008080;">127</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;arrayArgs.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">128</span> <span style="color: #0000ff;">if</span>(!<span style="color: #000000;">_checkFunc(arrayArgs[i])){<br/></span><span style="color: #008080;">129</span> <span style="color: #000000;"> _checkTask(arrayArgs[i]);<br/></span><span style="color: #008080;">130</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">131</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">132</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">133</span> <br/><span style="color: #008080;">134</span> <span style="color: #008000;">//</span><span style="color: #008000;">开始执行SubItem</span><br/><span style="color: #008080;">135</span> <span style="color: #0000ff;">var</span> _startSubItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(subItemIndex, context){<br/></span><span style="color: #008080;">136</span> <span style="color: #0000ff;">var</span> subItem =<span style="color: #000000;"> _subItems[subItemIndex];<br/></span><span style="color: #008080;">137</span> <span style="color: #008000;">//</span><span style="color: #008000;">如果subItem是方法和它的参数</span><br/><span style="color: #008080;">138</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(subItem.isFunc){<br/></span><span style="color: #008080;">139</span> <span style="color: #008000;">//</span><span style="color: #008000;">先获取方法的上下文环境(就是方法里面的this)</span><br/><span style="color: #008080;">140</span> <span style="color: #0000ff;">var</span> workItemCxt =<span style="color: #000000;"> context.getWorkItemContext(subItemIndex);<br/></span><span style="color: #008080;">141</span> <span style="color: #008000;">//</span><span style="color: #008000;">再执行方法</span><br/><span style="color: #008080;">142</span> <span style="color: #000000;"> subItem.func.apply(workItemCxt, subItem.args);<br/></span><span style="color: #008080;">143</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">144</span> <span style="color: #008000;">//</span><span style="color: #008000;">如果subItem是Task对象</span><br/><span style="color: #008080;">145</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">146</span> <span style="color: #008000;">//</span><span style="color: #008000;">如果task已经完成</span><br/><span style="color: #008080;">147</span> <span style="color: #0000ff;">if</span>(subItem.task.getStatus() ==<span style="color: #000000;"> TaskStatus.finished){<br/></span><span style="color: #008080;">148</span> <span style="color: #000000;"> context.end(subItem.task.getOutput(), subItemIndex)<br/></span><span style="color: #008080;">149</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">150</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">151</span> <span style="color: #008000;">//</span><span style="color: #008000;">先注册Task对象的完成事件</span><br/><span style="color: #008080;">152</span> subItem.task.finished(<span style="color: #0000ff;">function</span><span style="color: #000000;">(output){<br/></span><span style="color: #008080;">153</span> <span style="color: #000000;"> context.end(output, subItemIndex);<br/></span><span style="color: #008080;">154</span> <span style="color: #000000;"> });<br/></span><span style="color: #008080;">155</span> <span style="color: #008000;">//</span><span style="color: #008000;">再启动这个task</span><br/><span style="color: #008080;">156</span> <span style="color: #000000;"> subItem.task.start(context.inputParams);<br/></span><span style="color: #008080;">157</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">158</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">159</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">160</span> <span style="color: #0000ff;">this</span>.condition = ""<span style="color: #000000;">;<br/></span><span style="color: #008080;">161</span> <span style="color: #008000;">//</span><span style="color: #008000;">开始执行WorkItem</span><br/><span style="color: #008080;">162</span> <span style="color: #0000ff;">this</span>.start = <span style="color: #0000ff;">function</span><span style="color: #000000;">(context){<br/></span><span style="color: #008080;">163</span> <span style="color: #000000;"> context.setItemsCount(_subItems.length);<br/></span><span style="color: #008080;">164</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;_subItems.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">165</span> <span style="color: #000000;"> _startSubItem(i, context);<br/></span><span style="color: #008080;">166</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">167</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">168</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">169</span> <br/><span style="color: #008080;">170</span> <span style="color: #008000;">//</span><span style="color: #008000;">异步操作上下文</span><br/><span style="color: #008080;">171</span> <span style="color: #0000ff;">var</span> Context = <span style="color: #0000ff;">function</span><span style="color: #000000;">(endCallback, inputParams){<br/></span><span style="color: #008080;">172</span> <span style="color: #0000ff;">var</span> _this = <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">173</span> <span style="color: #008000;">//</span><span style="color: #008000;">Workitem里面的每一个Item会按各自的索引把返回值存到_rawOutputParams里,这样做的目的是为了方便后续操作的先决条件判断</span><br/><span style="color: #008080;">174</span> <span style="color: #0000ff;">var</span> _rawOutputParams =<span style="color: #000000;"> [];<br/></span><span style="color: #008080;">175</span> <span style="color: #008000;">//</span><span style="color: #008000;">子Item个数</span><br/><span style="color: #008080;">176</span> <span style="color: #0000ff;">var</span><span style="color: #000000;"> _itemCount;<br/></span><span style="color: #008080;">177</span> <span style="color: #008000;">//</span><span style="color: #008000;">先决条件的判断方法集合,判断的同时也会更新outputParams</span><br/><span style="color: #008080;">178</span> <span style="color: #0000ff;">var</span> _condition =<span style="color: #000000;"> {<br/></span><span style="color: #008080;">179</span> then: <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">180</span> _this.outputParams = _rawOutputParams[0<span style="color: #000000;">].value;<br/></span><span style="color: #008080;">181</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">182</span> <span style="color: #000000;"> },<br/></span><span style="color: #008080;">183</span> all: <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">184</span> _this.outputParams =<span style="color: #000000;"> [];<br/></span><span style="color: #008080;">185</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;_itemCount; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">186</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(_rawOutputParams[i]){<br/></span><span style="color: #008080;">187</span> _this.outputParams[i] =<span style="color: #000000;"> _rawOutputParams[i].value;<br/></span><span style="color: #008080;">188</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">189</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">190</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">191</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">192</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">193</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">194</span> <span style="color: #000000;"> },<br/></span><span style="color: #008080;">195</span> any: <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">196</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;_itemCount; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">197</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(_rawOutputParams[i]){<br/></span><span style="color: #008080;">198</span> _this.outputParams =<span style="color: #000000;"> _rawOutputParams[i].value;<br/></span><span style="color: #008080;">199</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">200</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">201</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">202</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">203</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">204</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">205</span> <br/><span style="color: #008080;">206</span> <span style="color: #008000;">//</span><span style="color: #008000;">异步操作的输入操作</span><br/><span style="color: #008080;">207</span> <span style="color: #0000ff;">this</span>.inputParams =<span style="color: #000000;"> inputParams;<br/></span><span style="color: #008080;">208</span> <span style="color: #008000;">//</span><span style="color: #008000;">最终异步操作上下文结束时的输出参数(一般是一个操作的输出参数,all条件的输出参数比较特殊,是一个数组,每一个元素对应每一个子Workitem的输出参数)</span><br/><span style="color: #008080;">209</span> <span style="color: #0000ff;">this</span>.outputParams = <span style="color: #0000ff;">null</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">210</span> <span style="color: #0000ff;">this</span>.setItemsCount = <span style="color: #0000ff;">function</span><span style="color: #000000;">(itemCount){<br/></span><span style="color: #008080;">211</span> _itemCount =<span style="color: #000000;"> itemCount;<br/></span><span style="color: #008080;">212</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">213</span> <span style="color: #008000;">//</span><span style="color: #008000;">测试_rawOutputParams对于key条件是否通过</span><br/><span style="color: #008080;">214</span> <span style="color: #0000ff;">this</span>.testCondition = <span style="color: #0000ff;">function</span><span style="color: #000000;">(key){<br/></span><span style="color: #008080;">215</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> _condition[key]();<br/></span><span style="color: #008080;">216</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">217</span> <span style="color: #008000;">//</span><span style="color: #008000;">索引为index的子Workitem完成时会调用这个方法</span><br/><span style="color: #008080;">218</span> <span style="color: #0000ff;">this</span>.end = <span style="color: #0000ff;">function</span><span style="color: #000000;">(output, index){<br/></span><span style="color: #008080;">219</span> _rawOutputParams[index] =<span style="color: #000000;"> {<br/></span><span style="color: #008080;">220</span> <span style="color: #000000;"> value: output<br/></span><span style="color: #008080;">221</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">222</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(endCallback){<br/></span><span style="color: #008080;">223</span> <span style="color: #000000;"> endCallback(output);<br/></span><span style="color: #008080;">224</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">225</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">226</span> <span style="color: #008000;">//</span><span style="color: #008000;">生成一个子Workitem执行时的上下文环境</span><br/><span style="color: #008080;">227</span> <span style="color: #0000ff;">this</span>.getWorkItemContext = <span style="color: #0000ff;">function</span><span style="color: #000000;">(index){<br/></span><span style="color: #008080;">228</span> <span style="color: #008000;">//</span><span style="color: #008000;">这个是子Item的上下文对象(就是this)</span><br/><span style="color: #008080;">229</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> {<br/></span><span style="color: #008080;">230</span> <span style="color: #008000;">//</span><span style="color: #008000;">传递给上下文的参数</span><br/><span style="color: #008080;">231</span> <span style="color: #000000;"> param: _this.inputParams,<br/></span><span style="color: #008080;">232</span> <span style="color: #008000;">//</span><span style="color: #008000;">调用end方法告知异步操作的完成</span><br/><span style="color: #008080;">233</span> end: <span style="color: #0000ff;">function</span><span style="color: #000000;">(output){<br/></span><span style="color: #008080;">234</span> <span style="color: #000000;"> _this.end(output, index);<br/></span><span style="color: #008080;">235</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">236</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">237</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">238</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">239</span> <br/><span style="color: #008080;">240</span> <span style="color: #008000;">//</span><span style="color: #008000;">Task的状态</span><br/><span style="color: #008080;">241</span> <span style="color: #0000ff;">var</span> TaskStatus =<span style="color: #000000;"> {<br/></span><span style="color: #008080;">242</span> <span style="color: #008000;">//</span><span style="color: #008000;">未开始</span><br/><span style="color: #008080;">243</span> pending: 0<span style="color: #000000;">,<br/></span><span style="color: #008080;">244</span> <span style="color: #008000;">//</span><span style="color: #008000;">正在进行</span><br/><span style="color: #008080;">245</span> doing: 1<span style="color: #000000;">,<br/></span><span style="color: #008080;">246</span> <span style="color: #008000;">//</span><span style="color: #008000;">已完成</span><br/><span style="color: #008080;">247</span> finished: 2<br/><span style="color: #008080;">248</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">249</span> <br/><span style="color: #008080;">250</span> <span style="color: #008000;">//</span><span style="color: #008000;">不定义具体形参,直接使用arguments</span><br/><span style="color: #008080;">251</span> window.Task = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">252</span> <span style="color: #0000ff;">var</span> _status =<span style="color: #000000;"> TaskStatus.pending;<br/></span><span style="color: #008080;">253</span> <span style="color: #0000ff;">var</span> _wItemQueue =<span style="color: #000000;"> [], _currentItem, _currentContext;<br/></span><span style="color: #008080;">254</span> <span style="color: #0000ff;">var</span> _eventManager = <span style="color: #0000ff;">new</span><span style="color: #000000;"> EventManager();<br/></span><span style="color: #008080;">255</span> <span style="color: #0000ff;">var</span><span style="color: #000000;"> _output;<br/></span><span style="color: #008080;">256</span> <span style="color: #008000;">//</span><span style="color: #008000;">初始化一个WorkItem,并添加到执行队列中</span><br/><span style="color: #008080;">257</span> <span style="color: #0000ff;">var</span> _initWorkItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(args){<br/></span><span style="color: #008080;">258</span> <span style="color: #0000ff;">var</span> arrayArgs =<span style="color: #000000;"> [];<br/></span><span style="color: #008080;">259</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0; i&lt;args.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">260</span> arrayArgs[i] =<span style="color: #000000;"> args[i];<br/></span><span style="color: #008080;">261</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">262</span> <span style="color: #0000ff;">var</span> item = <span style="color: #0000ff;">new</span><span style="color: #000000;"> WorkItem(arrayArgs);<br/></span><span style="color: #008080;">263</span> <span style="color: #000000;"> _wItemQueue.push(item);<br/></span><span style="color: #008080;">264</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> item;<br/></span><span style="color: #008080;">265</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">266</span> <span style="color: #008000;">//</span><span style="color: #008000;">设置item的先决条件</span><br/><span style="color: #008080;">267</span> <span style="color: #0000ff;">var</span> _setItemCondition = <span style="color: #0000ff;">function</span><span style="color: #000000;">(item, condition){<br/></span><span style="color: #008080;">268</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(condition){<br/></span><span style="color: #008080;">269</span> item.condition =<span style="color: #000000;"> condition;<br/></span><span style="color: #008080;">270</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">271</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">272</span> <span style="color: #008000;">//</span><span style="color: #008000;">试着执行下一个异步操作,如果这个操作满足他的先决条件,那就执行;如果已经式最后一个异步操作了,就触发完成事件</span><br/><span style="color: #008080;">273</span> <span style="color: #0000ff;">var</span> _tryDoNextItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(output){<br/></span><span style="color: #008080;">274</span> <span style="color: #0000ff;">var</span> next =<span style="color: #000000;"> _getCurNextItem();<br/></span><span style="color: #008080;">275</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(next){<br/></span><span style="color: #008080;">276</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(_currentContext.testCondition(next.condition)){<br/></span><span style="color: #008080;">277</span> _currentItem =<span style="color: #000000;"> next;<br/></span><span style="color: #008080;">278</span> <span style="color: #000000;"> _doCurrentItem();<br/></span><span style="color: #008080;">279</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">280</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">281</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">282</span> _status =<span style="color: #000000;"> TaskStatus.finished;<br/></span><span style="color: #008080;">283</span> _output =<span style="color: #000000;"> output;<br/></span><span style="color: #008080;">284</span> _eventManager.trigger("finish"<span style="color: #000000;">, output);<br/></span><span style="color: #008080;">285</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">286</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">287</span> <span style="color: #008000;">//</span><span style="color: #008000;">执行当前的Workitem</span><br/><span style="color: #008080;">288</span> <span style="color: #0000ff;">var</span> _doCurrentItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(contextParam){<br/></span><span style="color: #008080;">289</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(contextParam) {<br/></span><span style="color: #008080;">290</span> _currentContext = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Context(_tryDoNextItem, contextParam);<br/></span><span style="color: #008080;">291</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">292</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">293</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(_currentContext){<br/></span><span style="color: #008080;">294</span> _currentContext = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Context(_tryDoNextItem, _currentContext.outputParams);<br/></span><span style="color: #008080;">295</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">296</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{<br/></span><span style="color: #008080;">297</span> _currentContext = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Context(_tryDoNextItem);<br/></span><span style="color: #008080;">298</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">299</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">300</span> <span style="color: #000000;"> _currentItem.start(_currentContext);<br/></span><span style="color: #008080;">301</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">302</span> <span style="color: #008000;">//</span><span style="color: #008000;">获取下一个异步操作,如果已经是最后一个了返回undefined</span><br/><span style="color: #008080;">303</span> <span style="color: #0000ff;">var</span> _getCurNextItem = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">304</span> <span style="color: #0000ff;">var</span> i=0<span style="color: #000000;">;<br/></span><span style="color: #008080;">305</span> <span style="color: #0000ff;">for</span>(; i&lt;_wItemQueue.length; i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">306</span> <span style="color: #0000ff;">if</span>(_currentItem ==<span style="color: #000000;"> _wItemQueue[i]){<br/></span><span style="color: #008080;">307</span> <span style="color: #0000ff;">break</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">308</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">309</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">310</span> <span style="color: #0000ff;">return</span> _wItemQueue[i + 1<span style="color: #000000;">];<br/></span><span style="color: #008080;">311</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">312</span> _currentItem =<span style="color: #000000;"> _initWorkItem(arguments);<br/></span><span style="color: #008080;">313</span> <br/><span style="color: #008080;">314</span> <span style="color: #008000;">//</span><span style="color: #008000;">获取Task当前状态</span><br/><span style="color: #008080;">315</span> <span style="color: #0000ff;">this</span>.getStatus = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">316</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> _status;<br/></span><span style="color: #008080;">317</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">318</span> <span style="color: #008000;">//</span><span style="color: #008000;">获取Task完成时的输出参数</span><br/><span style="color: #008080;">319</span> <span style="color: #0000ff;">this</span>.getOutput = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">320</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> _output;<br/></span><span style="color: #008080;">321</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">322</span> <span style="color: #008000;">//</span><span style="color: #008000;">注册完成事件</span><br/><span style="color: #008080;">323</span> <span style="color: #0000ff;">this</span>.finished = <span style="color: #0000ff;">function</span><span style="color: #000000;">(callback){<br/></span><span style="color: #008080;">324</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(callback){<br/></span><span style="color: #008080;">325</span> _eventManager.addHandler("finish"<span style="color: #000000;">, callback);<br/></span><span style="color: #008080;">326</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">327</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">328</span> <span style="color: #008000;">//</span><span style="color: #008000;">任务开始(把do改成start是因为在ie下有问题,ie会把do当做保留字)</span><br/><span style="color: #008080;">329</span> <span style="color: #008000;">//</span><span style="color: #008000;">contextParam是一个上下文参数,可以在异步方法中通过this.Param引用</span><br/><span style="color: #008080;">330</span> <span style="color: #0000ff;">this</span>.start = <span style="color: #0000ff;">function</span><span style="color: #000000;">(contextParam){<br/></span><span style="color: #008080;">331</span> <span style="color: #0000ff;">if</span>(_status ==<span style="color: #000000;"> TaskStatus.pending){<br/></span><span style="color: #008080;">332</span> _status =<span style="color: #000000;"> TaskStatus.doing;<br/></span><span style="color: #008080;">333</span> <span style="color: #000000;"> _doCurrentItem(contextParam);<br/></span><span style="color: #008080;">334</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">335</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">336</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">337</span> <span style="color: #0000ff;">this</span>.then = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">338</span> <span style="color: #0000ff;">var</span> workItem =<span style="color: #000000;"> _initWorkItem(arguments);<br/></span><span style="color: #008080;">339</span> _setItemCondition(workItem, 'then'<span style="color: #000000;">);<br/></span><span style="color: #008080;">340</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">341</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">342</span> <span style="color: #0000ff;">this</span>.all = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">343</span> <span style="color: #0000ff;">var</span> workItem =<span style="color: #000000;"> _initWorkItem(arguments);<br/></span><span style="color: #008080;">344</span> _setItemCondition(workItem, 'all'<span style="color: #000000;">);<br/></span><span style="color: #008080;">345</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">346</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">347</span> <span style="color: #0000ff;">this</span>.any = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">348</span> <span style="color: #0000ff;">var</span> workItem =<span style="color: #000000;"> _initWorkItem(arguments);<br/></span><span style="color: #008080;">349</span> _setItemCondition(workItem, 'any'<span style="color: #000000;">);<br/></span><span style="color: #008080;">350</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">351</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">352</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">353</span> <span style="color: #000000;"> })();<br/></span><span style="color: #008080;">354</span> <br/><span style="color: #008080;">355</span> <br/><span style="color: #008080;">356</span> <span style="color: #0000ff;">var</span> taskExp_1 = <span style="color: #0000ff;">new</span> Task(readFile, ["aa.txt"]).then(resolveFile, ["/service/fileResolve.ashx?file=aa.txt"<span style="color: #000000;">]);<br/></span><span style="color: #008080;">357</span> <span style="color: #0000ff;">var</span> taskExp_2 = <span style="color: #0000ff;">new</span> Task(readFile, ["bb.txt"]).then(resolveFile, ["/service/fileResolve.ashx?file=bb.txt"<span style="color: #000000;">]);<br/></span><span style="color: #008080;">358</span> <span style="color: #0000ff;">var</span> taskExp_3 = <span style="color: #0000ff;">new</span> Task(taskExp_1, taskExp_2).all(writeFile, ["cc.txt"<span style="color: #000000;">]).then(sendMail).start();<br/></span><span style="color: #008080;">359</span> <br/><span style="color: #008080;">360</span> &lt;/script&gt;<br/><span style="color: #008080;">361</span> &lt;/body&gt;<br/><span style="color: #008080;">362</span> &lt;/html&gt;</div></div><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3869159" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/lihao123/p/3869159.html" target="_blank">一步一步实现基于Task的Promise库(二)all和any方法的设计和实现</a>,转载请注明。</p>http://www.cnblogs.com/changewu/p/3869169.html新技能get:Android应用优化技能之“延迟加载”术 - 小change世风日下,人心不古。如今四海虽看似太平,其实却暗藏杀机。大到一架飞机一辆公交,小到一个app,都会让您抓狂。越来越复杂的界面,越来越多的需求,对app来说本身来说就是一个噩耗,但在人类无穷的想象力,在功能模块无情的堆积之下,对于应用来说,要么瘦,要么死!那么如何瘦,怎么瘦?对广大爱美的程序员和产品和...2014-07-25T15:24:00Z2014-07-25T15:24:00Z小changehttp://www.cnblogs.com/changewu/<p>世风日下,人心不古。</p><p>如今四海虽看似太平,其实却暗藏杀机。大到一架飞机一辆公交,小到一个app,都会让您抓狂。</p><p>越来越复杂的界面,越来越多的需求,对app来说本身来说就是一个噩耗,但在人类无穷的想象力,在功能模块无情的堆积之下,对于应用来说,要么瘦,要么死!</p><p>那么如何瘦,怎么瘦?对广大爱美的程序员和产品和用户来说,只有简约,按需才是王道。</p><p><strong>旁白:写文章就写文章嘛,废话太多了!</strong></p><p><strong>【这是正题】</strong>上面一堆废话其实也是有两个有用的词汇的,<span style="background-color: #ffffff; color: #ff0000;">简约</span>和<span style="color: #ff0000;">按需<span style="color: #000000;">。简约是设计要想的,那么按需就是我们程序将要做的。</span></span></p><p><strong><span style="color: #ff0000;"><span style="color: #000000;">【按需:延迟加载】</span></span></strong><span style="color: #ff0000;"><span style="color: #000000;"><span style="color: #ff0000;">所谓的延迟加载就是不在初始化界面的时候加载部分view,在需要的时候才加载,在布局多控件的时候能有效的提升界面的加载和响应速度。</span></span></span></p><p><strong><span style="color: #000000;">【我们普遍在使用的按需加载】</span></strong><span style="color: #000000;">稍微有些经验的android开发程序员都会懂得把一些复杂界面里的一些模块单独用一个xml写的layout独立写,然后在需要的时候把它们inflate()到程序中来,这样达到延迟加载的目的。这样做在界面不确定,需要多次实例化view或者根据数据遍历产生view的时候会很方便,完全由java代码实现。那么如果我们在界面元素确定并且需要延时加载的时候有没有更直观的做法呢?当然有:使用viewStub.</span></p><p><strong><span style="color: #000000;">【一个轻量级的控件:viewStub】</span></strong><span style="color: #000000;">如名字的含义,只是一个view的存根,不占什么内存(区别于&lt;include&gt;),但却可以占个位置,在程序需要的时候把viewStub指向的view扩展到界面。依照惯例,在我要举例子的这个时候代码会悄悄袭来--》</span></p><p>&nbsp;</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;"> 1</span> &lt;ScrollView xmlns:android="http://schemas.android.com/apk/res/android"<br/><span style="color: #008080;"> 2</span> xmlns:tools="http://schemas.android.com/tools"<br/><span style="color: #008080;"> 3</span> android:layout_width="match_parent"<br/><span style="color: #008080;"> 4</span> android:layout_height="match_parent"<br/><span style="color: #008080;"> 5</span> tools:context=".MainActivity" &gt;<br/><span style="color: #008080;"> 6</span> <br/><span style="color: #008080;"> 7</span> &lt;<span style="color: #000000;">LinearLayout<br/></span><span style="color: #008080;"> 8</span> android:id="@+id/main"<br/><span style="color: #008080;"> 9</span> android:layout_width="match_parent"<br/><span style="color: #008080;">10</span> android:layout_height="wrap_content"<br/><span style="color: #008080;">11</span> android:orientation="vertical"<br/><span style="color: #008080;">12</span> android:paddingBottom="@dimen/activity_vertical_margin"<br/><span style="color: #008080;">13</span> android:paddingLeft="@dimen/activity_horizontal_margin"<br/><span style="color: #008080;">14</span> android:paddingRight="@dimen/activity_horizontal_margin"<br/><span style="color: #008080;">15</span> android:paddingTop="@dimen/activity_vertical_margin" &gt;<br/><span style="color: #008080;">16</span> <br/><span style="color: #008080;">17</span> &lt;<span style="color: #000000;">TextView<br/></span><span style="color: #008080;">18</span> android:layout_width="wrap_content"<br/><span style="color: #008080;">19</span> android:layout_height="wrap_content"<br/><span style="color: #008080;">20</span> android:text="所谓的延时加载就是不在初始化界面的时候加载部分view,在需要的时候才加载,在布局多控件的时候能有效的提升界面的响应速度。"/&gt;<br/><span style="color: #008080;">21</span> <br/><span style="color: #008080;">22</span> &lt;<span style="color: #000000;">Button<br/></span><span style="color: #008080;">23</span> android:id="@+id/btn_by_inflate"<br/><span style="color: #008080;">24</span> android:layout_width="match_parent"<br/><span style="color: #008080;">25</span> android:layout_height="wrap_content"<br/><span style="color: #008080;">26</span> android:text="普通inflate方式" /&gt;<br/><span style="color: #008080;">27</span> <br/><span style="color: #008080;">28</span> &lt;<span style="color: #000000;">Button<br/></span><span style="color: #008080;">29</span> android:id="@+id/btn_by_viewstub"<br/><span style="color: #008080;">30</span> android:layout_width="match_parent"<br/><span style="color: #008080;">31</span> android:layout_height="wrap_content"<br/><span style="color: #008080;">32</span> android:text="viewStub方式" /&gt;<br/><span style="color: #008080;">33</span> <br/><span style="color: #008080;">34</span> <span style="color: #ff0000;">&lt;ViewStub<br/>35 android:id="@+id/viewstub"<br/>36 android:layout_width="match_parent"<br/>37 android:layout_height="wrap_content"<br/>38 android:inflatedId="@+id/inflate_view_id"<br/>39 android:layout="@layout/delay_by_viewstub" /&gt;</span><br/><span style="color: #008080;">40</span> &lt;/LinearLayout&gt;<br/><span style="color: #008080;">41</span> <br/><span style="color: #008080;">42</span> &lt;/ScrollView&gt;</div><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p><span style="line-height: 1.5;">这是我们主界面xml中定义的ViewStub,需要注意的有三点:id-&gt;stub的id,根据这个取stub对象;inflatedId-&gt;扩展出的视图id(即指向的视图的id,可以不定义);layout-&gt;将要inflate的layout。好的,太直观了,不用再解释什么了。</span></p><p>有了存根,那么我们怎么在程序需要的时候取得?寥寥几句,view轻松到手。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">package</span><span style="color: #000000;"> com.change.delayloaddemo;<br/></span><span style="color: #008080;"> 2</span> <br/><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.app.Activity;<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.graphics.Color;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.os.Bundle;<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.view.Menu;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.view.View;<br/></span><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.view.View.OnClickListener;<br/></span><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.view.ViewStub;<br/></span><span style="color: #008080;">10</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.widget.Button;<br/></span><span style="color: #008080;">11</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.widget.LinearLayout;<br/></span><span style="color: #008080;">12</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> android.widget.TextView;<br/></span><span style="color: #008080;">13</span> <br/><span style="color: #008080;">14</span> <span style="color: #008000;">/**</span><br/><span style="color: #008080;">15</span> <span style="color: #008000;"> * 两种延迟加载方式Demo android推荐采用viewStub方式。<br/></span><span style="color: #008080;">16</span> <span style="color: #008000;"> * <br/></span><span style="color: #008080;">17</span> <span style="color: #008000;"> * </span><span style="color: #808080;">@author</span><span style="color: #008000;"> Change<br/></span><span style="color: #008080;">18</span> <span style="color: #008000;"> * <br/></span><span style="color: #008080;">19</span> <span style="color: #008000;">*/</span><br/><span style="color: #008080;">20</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> MainActivity <span style="color: #0000ff;">extends</span> Activity <span style="color: #0000ff;">implements</span><span style="color: #000000;"> OnClickListener {<br/></span><span style="color: #008080;">21</span> <span style="color: #0000ff;">private</span><span style="color: #000000;"> LinearLayout main;<br/></span><span style="color: #008080;">22</span> <span style="color: #0000ff;">private</span><span style="color: #000000;"> TextView normalInflate, delayByViewStub;<br/></span><span style="color: #008080;">23</span> <span style="color: #0000ff;">private</span><span style="color: #000000;"> ViewStub mStub;<br/></span><span style="color: #008080;">24</span> <span style="color: #0000ff;">private</span><span style="color: #000000;"> Button byInflate, byViewStub;<br/></span><span style="color: #008080;">25</span> <br/><span style="color: #008080;">26</span> <span style="color: #000000;"> @Override<br/></span><span style="color: #008080;">27</span> <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> onCreate(Bundle savedInstanceState) {<br/></span><span style="color: #008080;">28</span> <span style="color: #0000ff;">super</span><span style="color: #000000;">.onCreate(savedInstanceState);<br/></span><span style="color: #008080;">29</span> <span style="color: #000000;"> setContentView(R.layout.activity_main);<br/></span><span style="color: #008080;">30</span> <span style="color: #000000;"> initViews();<br/></span><span style="color: #008080;">31</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">32</span> <br/><span style="color: #008080;">33</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> initViews(){<br/></span><span style="color: #008080;">34</span> main =<span style="color: #000000;"> (LinearLayout) findViewById(R.id.main);<br/></span><span style="color: #008080;">35</span> byInflate =<span style="color: #000000;"> (Button)findViewById(R.id.btn_by_inflate);<br/></span><span style="color: #008080;">36</span> byViewStub =<span style="color: #000000;"> (Button)findViewById(R.id.btn_by_viewstub);<br/></span><span style="color: #008080;">37</span> <br/><span style="color: #008080;">38</span> byInflate.setOnClickListener(<span style="color: #0000ff;">this</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">39</span> byViewStub.setOnClickListener(<span style="color: #0000ff;">this</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">40</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">41</span> <br/><span style="color: #008080;">42</span> <span style="color: #000000;"> @Override<br/></span><span style="color: #008080;">43</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> onCreateOptionsMenu(Menu menu) {<br/></span><span style="color: #008080;">44</span> <span style="color: #008000;">//</span><span style="color: #008000;"> Inflate the menu; this adds items to the action bar if it is present.</span><br/><span style="color: #008080;">45</span> <span style="color: #000000;"> getMenuInflater().inflate(R.menu.main, menu);<br/></span><span style="color: #008080;">46</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">47</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">48</span> <br/><span style="color: #008080;">49</span> <span style="color: #000000;"> @Override<br/></span><span style="color: #008080;">50</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> onClick(View arg0) {<br/></span><span style="color: #008080;">51</span> <span style="color: #0000ff;">switch</span><span style="color: #000000;"> (arg0.getId()) {<br/></span><span style="color: #008080;">52</span> <span style="color: #0000ff;">case</span><span style="color: #000000;"> R.id.btn_by_inflate:<br/></span><span style="color: #008080;">53</span> normalInflate =<span style="color: #000000;"> (TextView) getLayoutInflater().inflate(<br/></span><span style="color: #008080;">54</span> R.layout.delay_by_viewstub, <span style="color: #0000ff;">null</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">55</span> <span style="color: #000000;"> main.addView(normalInflate);<br/></span><span style="color: #008080;">56</span> normalInflate.setText("我是通常的inflate方法加载的view"<span style="color: #000000;">);<br/></span><span style="color: #008080;">57</span> normalInflate.setBackgroundColor(Color.parseColor("#00ffff"<span style="color: #000000;">));<br/></span><span style="color: #008080;">58</span> <span style="color: #0000ff;">break</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">59</span> <span style="color: #0000ff;">case</span><span style="color: #000000;"> R.id.btn_by_viewstub:<br/></span><span style="color: #008080;">60</span> <span style="color: #ff0000;"> mStub = (ViewStub)findViewById(R.id.viewstub);<br/>61 if(null!=mStub)//mStub执行了一次inflate()方法之后会被置空,所以此处判空<br/>62 delayByViewStub = (TextView)mStub.inflate();<br/>63 // mStub.setVisibility(View.VISIBLE);//或者这样可以inflate出view.</span><br/><span style="color: #008080;">64</span> <span style="color: #0000ff;">break</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">65</span> <br/><span style="color: #008080;">66</span> <span style="color: #0000ff;">default</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">67</span> <span style="color: #0000ff;">break</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">68</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">69</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">70</span> <br/><span style="color: #008080;">71</span> }</div><p>以上红色部分便是使用viewStub延迟加载的几句代码。</p><p><strong style="line-height: 1.5;">【需要注意的点】</strong><span style="line-height: 1.5; color: #ff0000;">viewStub在执行完inflate()方法或者setVisibility(View.VISIBLE)方法之后会被置空,不能再使用该对象。</span></p><p><span style="color: #000000;"><strong>【完整代码】</strong>demo的github地址:<span style="color: #ff0000;">https://github.com/ChangeWu/SomePoject/tree/master/DelayLoadDemo</span></span></p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3869169" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/changewu/p/3869169.html" target="_blank">新技能get:Android应用优化技能之“延迟加载”术</a>,转载请注明。</p>http://www.cnblogs.com/wunaozai/p/3869101.html利用yacc和lex制作一个小的计算器 - 无脑仔的小明买了本《自制编程语言》,这本书有点难,目前只是看前两章,估计后面的章节,最近一段时间是不会看了,真的是好难啊!! 由于本人是身处弱校,学校的课程没有编译原理这一门课,所以就想看这两章,了解一下编译原理,增加一下自己的软实力。免得被别人鄙视。 一、安装yacc和lex 我是在Windows下...2014-07-25T15:20:00Z2014-07-25T15:20:00Z无脑仔的小明http://www.cnblogs.com/wunaozai/<p><span style="font-size: 16px;">  买了本《自制编程语言》,这本书有点难,目前只是看前两章,估计后面的章节,最近一段时间是不会看了,真的是好难啊!!</span><br /><span style="font-size: 16px;">  由于本人是身处弱校,学校的课程没有编译原理这一门课,所以就想看这两章,了解一下编译原理,增加一下自己的软实力。免得被别人鄙视。</span></p><p><strong><span style="font-size: 16px;">  一、安装yacc和lex</span></strong></p><p><span style="font-size: 16px;">  我是在Windows下使用这两个软件的。所以使用bison代替yacc,用flex代替lex。两者的下载地址是<a href="http://sourceforge.net/projects/winflexbison/">http://sourceforge.net/projects/winflexbison/</a> 我的gcc环境是使用以前用过的mingw。我们吧解压后的flex和bison放到mingw的bin目录下。这一步就完成了。</span></p><p><strong><span style="font-size: 16px;">  二、编译代码</span></strong></p><p><span style="font-size: 16px;">  先编译代码,看一下结果,然后在分析。在这本书中提供的一个网址有书中代码下载。下载地址&nbsp;<a href="http://avnpc.com/pages/devlang">http://avnpc.com/pages/devlang</a>&nbsp;下载后找到mycalc这个文件夹。然后执行下面进行编译</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">1</span> bison --yacc -dv mycalc.y -<span style="color: #000000;">o y.tab.c<br/></span><span style="color: #008080;">2</span> <span style="color: #000000;">flex mycalc.l<br/></span><span style="color: #008080;">3</span> <span style="color: #0000ff;">gcc</span> -o mycalc y.tab.c lex.yy.c</div><p><strong><span style="font-size: 16px;">  三、yacc/lex是什么</span></strong></p><p><span style="font-size: 16px;">     一般编程语言的语法处理,都会有以下的过程。</span><br /><span style="font-size: 16px;">   1.词法分析</span><br /><span style="font-size: 16px;">    将源代码分割成若干个记号的处理。</span></p><p><span style="font-size: 16px;">   2.语法分析</span></p><p><span style="font-size: 16px;">    即从记号构建分析树的处理。分析树也叫作语法树或抽象语法树。</span></p><p><span style="font-size: 16px;">   3.语义分析</span></p><p><span style="font-size: 16px;">    经过语法分析生成的分析树,并不包含数据类型等语义信息。因此在语义分析阶段,会检查程序中是否含有语法正确但是存在逻辑问题的错误。</span></p><p><span style="font-size: 16px;">   4.生成代码</span></p><p><span style="font-size: 16px;">    如果是C语言等生成机器码的编译器或Java这样生成字节码的编译器,在分析树构建完毕后会进入代码生成阶段。</span></p><p><span style="font-size: 16px;">    例如有下面源代码</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">1</span> <span style="color: #0000ff;">if</span>(a==<span style="color: #800080;">10</span><span style="color: #000000;">)<br/></span><span style="color: #008080;">2</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">3</span> printf(<span style="color: #800000;">"</span><span style="color: #800000;">hoge\n</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">4</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;">5</span> <span style="color: #0000ff;">else</span><br/><span style="color: #008080;">6</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">7</span> printf(<span style="color: #800000;">"</span><span style="color: #800000;">piyo\n</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">8</span> }</div><p>    <span style="font-size: 16px;">执行词法分析后,将被分割为如下的记号(每一块就是一个记号)</span></p><p><img src="http://images.cnitblog.com/i/485067/201407/252134342136390.png" alt="" /></p><p><span style="font-size: 16px;">    对此进行语法分析后构建的分析树,如下图所示</span></p><p><img src="http://images.cnitblog.com/i/485067/201407/252141449792255.png" alt="" /></p><p><span style="font-size: 16px;">    执行词法分析的程序称为词法分析器。lex的工作就是根据词法规则自动生成词法分析器。</span></p><p><span style="font-size: 16px;">    执行语法分析的程序则称为解析器。yacc就是根据语法规则自动生成解析器的程序。</span></p><p><strong><span style="font-size: 16px;">  四、分析计算器代码</span></strong></p><p><span style="font-size: 16px;">    1.mycalc.l源代码</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;"> 1</span> %<span style="color: #000000;">{<br/></span><span style="color: #008080;"> 2</span> #include &lt;stdio.h&gt;<br/><span style="color: #008080;"> 3</span> #include <span style="color: #800000;">"</span><span style="color: #800000;">y.tab.h</span><span style="color: #800000;">"</span><br/><span style="color: #008080;"> 4</span> <br/><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">int</span><br/><span style="color: #008080;"> 6</span> yywrap(<span style="color: #0000ff;">void</span><span style="color: #000000;">)<br/></span><span style="color: #008080;"> 7</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">return</span> <span style="color: #800080;">1</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 9</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;">10</span> %<span style="color: #000000;">}<br/></span><span style="color: #008080;">11</span> %%<br/><span style="color: #008080;">12</span> <span style="color: #800000;">"</span><span style="color: #800000;">+</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> ADD;<br/></span><span style="color: #008080;">13</span> <span style="color: #800000;">"</span><span style="color: #800000;">-</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> SUB;<br/></span><span style="color: #008080;">14</span> <span style="color: #800000;">"</span><span style="color: #800000;">*</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> MUL;<br/></span><span style="color: #008080;">15</span> <span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> DIV;<br/></span><span style="color: #008080;">16</span> <span style="color: #800000;">"</span><span style="color: #800000;">\n</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> CR;<br/></span><span style="color: #008080;">17</span> ([<span style="color: #800080;">1</span>-<span style="color: #800080;">9</span>][<span style="color: #800080;">0</span>-<span style="color: #800080;">9</span>]*)|<span style="color: #800080;">0</span>|([<span style="color: #800080;">0</span>-<span style="color: #800080;">9</span>]+\.[<span style="color: #800080;">0</span>-<span style="color: #800080;">9</span>]*<span style="color: #000000;">) {<br/></span><span style="color: #008080;">18</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> temp;<br/></span><span style="color: #008080;">19</span> sscanf(yytext, <span style="color: #800000;">"</span><span style="color: #800000;">%lf</span><span style="color: #800000;">"</span>, &amp;<span style="color: #000000;">temp);<br/></span><span style="color: #008080;">20</span> yylval.double_value =<span style="color: #000000;"> temp;<br/></span><span style="color: #008080;">21</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> DOUBLE_LITERAL;<br/></span><span style="color: #008080;">22</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;">23</span> <span style="color: #000000;">[ \t] ;<br/></span><span style="color: #008080;">24</span> <span style="color: #000000;">. {<br/></span><span style="color: #008080;">25</span> fprintf(stderr, <span style="color: #800000;">"</span><span style="color: #800000;">lexical error.\n</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">26</span> exit(<span style="color: #800080;">1</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">27</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;">28</span> %%</div><p><span style="font-size: 16px;">    第一行到第十行是一个定义区块,lex中用 %{...}%定义,这里面代码将原样输出。</span></p><p><span style="font-size: 16px;">    第11行到第28行是一个规则区块。语法大概就是前面一部分是使用正则表达式后面一部分是返回匹配到后这一部分是类型标记。大括号里面是动作。例如&nbsp;([1-9][0-9]*)|0|([0-9]+\.[0-9]*)是匹配小数,然后对这个小数进行sscanf处理后返回一个DOUBLE_LITERAL类型。</span></p><p><span style="font-size: 16px;">    2.mycalc.y 源代码</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;"> 1</span> %<span style="color: #000000;">{<br/></span><span style="color: #008080;"> 2</span> #include &lt;stdio.h&gt;<br/><span style="color: #008080;"> 3</span> #include &lt;stdlib.h&gt;<br/><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">#define</span> YYDEBUG 1<br/><span style="color: #008080;"> 5</span> %<span style="color: #000000;">}<br/></span><span style="color: #008080;"> 6</span> %<span style="color: #000000;">union {<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> int_value;<br/></span><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> double_value;<br/></span><span style="color: #008080;"> 9</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;">10</span> %token &lt;double_value&gt;<span style="color: #000000;"> DOUBLE_LITERAL<br/></span><span style="color: #008080;">11</span> %<span style="color: #000000;">token ADD SUB MUL DIV CR<br/></span><span style="color: #008080;">12</span> %type &lt;double_value&gt;<span style="color: #000000;"> expression term primary_expression<br/></span><span style="color: #008080;">13</span> %%<br/><span style="color: #008080;">14</span> <span style="color: #000000;">line_list<br/></span><span style="color: #008080;">15</span> <span style="color: #000000;"> : line<br/></span><span style="color: #008080;">16</span> |<span style="color: #000000;"> line_list line<br/></span><span style="color: #008080;">17</span> <span style="color: #000000;"> ;<br/></span><span style="color: #008080;">18</span> <span style="color: #000000;">line<br/></span><span style="color: #008080;">19</span> <span style="color: #000000;"> : expression CR<br/></span><span style="color: #008080;">20</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">21</span> printf(<span style="color: #800000;">"</span><span style="color: #800000;">&gt;&gt;%lf\n</span><span style="color: #800000;">"</span>, $<span style="color: #800080;">1</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">22</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">23</span> <span style="color: #000000;">expression<br/></span><span style="color: #008080;">24</span> <span style="color: #000000;"> : term<br/></span><span style="color: #008080;">25</span> |<span style="color: #000000;"> expression ADD term<br/></span><span style="color: #008080;">26</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">27</span> $$ = $<span style="color: #800080;">1</span> + $<span style="color: #800080;">3</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">28</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">29</span> |<span style="color: #000000;"> expression SUB term<br/></span><span style="color: #008080;">30</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">31</span> $$ = $<span style="color: #800080;">1</span> - $<span style="color: #800080;">3</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">32</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">33</span> <span style="color: #000000;"> ;<br/></span><span style="color: #008080;">34</span> <span style="color: #000000;">term<br/></span><span style="color: #008080;">35</span> <span style="color: #000000;"> : primary_expression<br/></span><span style="color: #008080;">36</span> |<span style="color: #000000;"> term MUL primary_expression <br/></span><span style="color: #008080;">37</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">38</span> $$ = $<span style="color: #800080;">1</span> * $<span style="color: #800080;">3</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">39</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">40</span> |<span style="color: #000000;"> term DIV primary_expression<br/></span><span style="color: #008080;">41</span> <span style="color: #000000;"> {<br/></span><span style="color: #008080;">42</span> $$ = $<span style="color: #800080;">1</span> / $<span style="color: #800080;">3</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">43</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">44</span> <span style="color: #000000;"> ;<br/></span><span style="color: #008080;">45</span> <span style="color: #000000;">primary_expression<br/></span><span style="color: #008080;">46</span> <span style="color: #000000;"> : DOUBLE_LITERAL<br/></span><span style="color: #008080;">47</span> <span style="color: #000000;"> ; <br/></span><span style="color: #008080;">48</span> %%<br/><span style="color: #008080;">49</span> <span style="color: #0000ff;">int</span><br/><span style="color: #008080;">50</span> yyerror(<span style="color: #0000ff;">char</span> <span style="color: #0000ff;">const</span> *<span style="color: #000000;">str)<br/></span><span style="color: #008080;">51</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">52</span> <span style="color: #0000ff;">extern</span> <span style="color: #0000ff;">char</span> *<span style="color: #000000;">yytext;<br/></span><span style="color: #008080;">53</span> fprintf(stderr, <span style="color: #800000;">"</span><span style="color: #800000;">parser error near %s\n</span><span style="color: #800000;">"</span><span style="color: #000000;">, yytext);<br/></span><span style="color: #008080;">54</span> <span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">55</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;">56</span> <br/><span style="color: #008080;">57</span> <span style="color: #0000ff;">int</span> main(<span style="color: #0000ff;">void</span><span style="color: #000000;">)<br/></span><span style="color: #008080;">58</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">59</span> <span style="color: #0000ff;">extern</span> <span style="color: #0000ff;">int</span> yyparse(<span style="color: #0000ff;">void</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">60</span> <span style="color: #0000ff;">extern</span> FILE *<span style="color: #000000;">yyin;<br/></span><span style="color: #008080;">61</span> <br/><span style="color: #008080;">62</span> yyin =<span style="color: #000000;"> stdin;<br/></span><span style="color: #008080;">63</span> <span style="color: #0000ff;">if</span><span style="color: #000000;"> (yyparse()) {<br/></span><span style="color: #008080;">64</span> fprintf(stderr, <span style="color: #800000;">"</span><span style="color: #800000;">Error ! Error ! Error !\n</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">65</span> exit(<span style="color: #800080;">1</span><span style="color: #000000;">);<br/></span><span style="color: #008080;">66</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">67</span> }</div><p><span style="font-size: 16px;">    上面第13行到第48行,语法规则简化为下面格式</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #000000;">A<br/> : B C<br/> </span>|<span style="color: #000000;"> D<br/> ;</span></div><p><span style="font-size: 16px;">    即A的定义是B与C的组合,或者为D。</span></p><p><span style="font-size: 16px;">    上面的过程可以用一个游戏的方式解释。就是一个数字是定位为DOUBLE_LITERAL类型,通过第45行的规则可以将DOUBLE_LITERAL升级成primary_expression类型,然后通过34行规则可以升级为term类型。又term类型可以升级为expression类型。所以 &ldquo;2+4&rdquo; 符合的规则是数字2升级到expression类型,而当数字4升级到term类型时,此时的状态是 expression ADD term 通过第25行的规则可以得到两者的结合,得到一个term类型。(PS:这个时候让我想起了一个动漫,就是数码宝贝,类型可以进行进化,进化,超进化,究极进化,还可以合体进化。&lt;笑&gt;)上面一个专业的叫法是叫做归约。</span></p><p><span style="font-size: 16px;">    由于归约情况比较复杂和不好讲,我就截书本上的原图进行讲解吧。</span></p><p><img src="http://images.cnitblog.com/i/485067/201407/252224546359899.jpg" alt="" /></p><p><img src="http://images.cnitblog.com/i/485067/201407/252228584005661.jpg" alt="" /></p><p><img src="http://images.cnitblog.com/i/485067/201407/252231485881336.jpg" alt="" /></p><p><span style="font-size: 16px;">    至于左结合或右结合是由写的词法分析器来决定的。例如给出的代码,为什么是右结合呢,是因为用到了递归,所以会首先和低级的类型进行结合,这就是为什么MUL,DIV是term类型,ADD,SUB是expression类型,就是处理优先级的问题。</span></p><blockquote><p>对于C或Java有这样的一个问题</p><p>  a+++++b;</p><p>我们可以分析为a++ + ++b 为什么编译器还会报错呢?是因为我们如果定义优先级的话,++优先级大于+。那么在代码中就是实现为尽量使++在一起,而不是+优先,如果是+优先的话,那么每次都不会结合为++。所以代码在词法分析器阶段代码就会被分割成a ++ ++ + b ;这样几段。从而错误的。由于词法分析器和解析器是各自独立的。又因为词法分析器先于语法分析器运行。</p></blockquote><p><span style="font-size: 16px;">&nbsp;   上面的过程就是这样进行语法分析的。上面的过程虽然简单,但是如果用代码实现就有点困难了。我们使用yacc生成的执行文件就是对上面模拟的执行代码,使用yacc自动生成的。如果我们要自制编程语言的话,那么这个过程就要自己写了。因为有很多细节问题。不过不多说了,我们先了解这个就行。生成后的代码文件是y.tab.c y.tab.h 。生成的代码有几十K呢,我们要了解这个过程还是比较难的。</span></p><p><strong><span style="font-size: 16px;">  五、用代码实现词法分析器</span></strong></p><p><span style="font-size: 16px;">   该代码在calc/llparser目录下</span></p><p><span style="font-size: 16px;">   lexicalanalyzer.c</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('1eb84922-fc5a-4e3c-b2d1-8602edd8db5d')"><div id="cnblogs_code_open_1eb84922-fc5a-4e3c-b2d1-8602edd8db5d" class="cnblogs_code_hide"><span style="color: #008080;"> 1</span> #include &lt;stdio.h&gt;<br/><span style="color: #008080;"> 2</span> #include &lt;stdlib.h&gt;<br/><span style="color: #008080;"> 3</span> #include &lt;ctype.h&gt;<br/><span style="color: #008080;"> 4</span> #include <span style="color: #800000;">"</span><span style="color: #800000;">token.h</span><span style="color: #800000;">"</span><br/><span style="color: #008080;"> 5</span> <br/><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">char</span> *<span style="color: #000000;">st_line;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> st_line_pos;<br/></span><span style="color: #008080;"> 8</span> <br/><span style="color: #008080;"> 9</span> typedef <span style="color: #0000ff;">enum</span><span style="color: #000000;"> {<br/></span><span style="color: #008080;"> 10</span> <span style="color: #000000;"> INITIAL_STATUS,<br/></span><span style="color: #008080;"> 11</span> <span style="color: #000000;"> IN_INT_PART_STATUS,<br/></span><span style="color: #008080;"> 12</span> <span style="color: #000000;"> DOT_STATUS,<br/></span><span style="color: #008080;"> 13</span> <span style="color: #000000;"> IN_FRAC_PART_STATUS<br/></span><span style="color: #008080;"> 14</span> <span style="color: #000000;">} LexerStatus;<br/></span><span style="color: #008080;"> 15</span> <br/><span style="color: #008080;"> 16</span> <span style="color: #0000ff;">void</span><br/><span style="color: #008080;"> 17</span> get_token(Token *<span style="color: #000000;">token)<br/></span><span style="color: #008080;"> 18</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;"> 19</span> <span style="color: #0000ff;">int</span> out_pos = <span style="color: #800080;">0</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 20</span> LexerStatus status =<span style="color: #000000;"> INITIAL_STATUS;<br/></span><span style="color: #008080;"> 21</span> <span style="color: #0000ff;">char</span><span style="color: #000000;"> current_char;<br/></span><span style="color: #008080;"> 22</span> <br/><span style="color: #008080;"> 23</span> token-&gt;kind =<span style="color: #000000;"> BAD_TOKEN;<br/></span><span style="color: #008080;"> 24</span> <span style="color: #0000ff;">while</span> (st_line[st_line_pos] != <span style="color: #800000;">'</span><span style="color: #800000;">\0</span><span style="color: #800000;">'</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 25</span> current_char =<span style="color: #000000;"> st_line[st_line_pos];<br/></span><span style="color: #008080;"> 26</span> <span style="color: #0000ff;">if</span> ((status == IN_INT_PART_STATUS || status ==<span style="color: #000000;"> IN_FRAC_PART_STATUS)<br/></span><span style="color: #008080;"> 27</span> &amp;&amp; !isdigit(current_char) &amp;&amp; current_char != <span style="color: #800000;">'</span><span style="color: #800000;">.</span><span style="color: #800000;">'</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 28</span> token-&gt;kind =<span style="color: #000000;"> NUMBER_TOKEN;<br/></span><span style="color: #008080;"> 29</span> sscanf(token-&gt;str, <span style="color: #800000;">"</span><span style="color: #800000;">%lf</span><span style="color: #800000;">"</span>, &amp;token-&gt;<span style="color: #000000;">value);<br/></span><span style="color: #008080;"> 30</span> <span style="color: #0000ff;">return</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 31</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 32</span> <span style="color: #0000ff;">if</span><span style="color: #000000;"> (isspace(current_char)) {<br/></span><span style="color: #008080;"> 33</span> <span style="color: #0000ff;">if</span> (current_char == <span style="color: #800000;">'</span><span style="color: #800000;">\n</span><span style="color: #800000;">'</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 34</span> token-&gt;kind =<span style="color: #000000;"> END_OF_LINE_TOKEN;<br/></span><span style="color: #008080;"> 35</span> <span style="color: #0000ff;">return</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 36</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 37</span> st_line_pos++<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 38</span> <span style="color: #0000ff;">continue</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 39</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 40</span> <br/><span style="color: #008080;"> 41</span> <span style="color: #0000ff;">if</span> (out_pos &gt;= MAX_TOKEN_SIZE-<span style="color: #800080;">1</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 42</span> fprintf(stderr, <span style="color: #800000;">"</span><span style="color: #800000;">token too long.\n</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/></span><span style="color: #008080;"> 43</span> exit(<span style="color: #800080;">1</span><span style="color: #000000;">);<br/></span><span style="color: #008080;"> 44</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 45</span> token-&gt;str[out_pos] =<span style="color: #000000;"> st_line[st_line_pos];<br/></span><span style="color: #008080;"> 46</span> st_line_pos++<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 47</span> out_pos++<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 48</span> token-&gt;str[out_pos] = <span style="color: #800000;">'</span><span style="color: #800000;">\0</span><span style="color: #800000;">'</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 49</span> <br/><span style="color: #008080;"> 50</span> <span style="color: #0000ff;">if</span> (current_char == <span style="color: #800000;">'</span><span style="color: #800000;">+</span><span style="color: #800000;">'</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 51</span> token-&gt;kind =<span style="color: #000000;"> ADD_OPERATOR_TOKEN;<br/></span><span style="color: #008080;"> 52</span> <span style="color: #0000ff;">return</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 53</span> } <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (current_char == <span style="color: #800000;">'</span><span style="color: #800000;">-</span><span style="color: #800000;">'</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 54</span> token-&gt;kind =<span style="color: #000000;"> SUB_OPERATOR_TOKEN;<br/></span><span style="color: #008080;"> 55</span> <span style="color: #0000ff;">return</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 56</span> } <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (current_char == <span style="color: #800000;">'</span><span style="color: #800000;">*</span><span style="color: #800000;">'</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 57</span> token-&gt;kind =<span style="color: #000000;"> MUL_OPERATOR_TOKEN;<br/></span><span style="color: #008080;"> 58</span> <span style="color: #0000ff;">return</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 59</span> } <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (current_char == <span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 60</span> token-&gt;kind =<span style="color: #000000;"> DIV_OPERATOR_TOKEN;<br/></span><span style="color: #008080;"> 61</span> <span style="color: #0000ff;">return</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 62</span> } <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span><span style="color: #000000;"> (isdigit(current_char)) {<br/></span><span style="color: #008080;"> 63</span> <span style="color: #0000ff;">if</span> (status ==<span style="color: #000000;"> INITIAL_STATUS) {<br/></span><span style="color: #008080;"> 64</span> status =<span style="color: #000000;"> IN_INT_PART_STATUS;<br/></span><span style="color: #008080;"> 65</span> } <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (status ==<span style="color: #000000;"> DOT_STATUS) {<br/></span><span style="color: #008080;"> 66</span> status =<span style="color: #000000;"> IN_FRAC_PART_STATUS;<br/></span><span style="color: #008080;"> 67</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 68</span> } <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (current_char == <span style="color: #800000;">'</span><span style="color: #800000;">.</span><span style="color: #800000;">'</span><span style="color: #000000;">) {<br/></span><span style="color: #008080;"> 69</span> <span style="color: #0000ff;">if</span> (status ==<span style="color: #000000;"> IN_INT_PART_STATUS) {<br/></span><span style="color: #008080;"> 70</span> status =<span style="color: #000000;"> DOT_STATUS;<br/></span><span style="color: #008080;"> 71</span> } <span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/></span><span style="color: #008080;"> 72</span> fprintf(stderr, <span style="color: #800000;">"</span><span style="color: #800000;">syntax error.\n</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/></span><span style="color: #008080;"> 73</span> exit(<span style="color: #800080;">1</span><span style="color: #000000;">);<br/></span><span style="color: #008080;"> 74</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 75</span> } <span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/></span><span style="color: #008080;"> 76</span> fprintf(stderr, <span style="color: #800000;">"</span><span style="color: #800000;">bad character(%c)\n</span><span style="color: #800000;">"</span><span style="color: #000000;">, current_char);<br/></span><span style="color: #008080;"> 77</span> exit(<span style="color: #800080;">1</span><span style="color: #000000;">);<br/></span><span style="color: #008080;"> 78</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 79</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;"> 80</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;"> 81</span> <br/><span style="color: #008080;"> 82</span> <span style="color: #0000ff;">void</span><br/><span style="color: #008080;"> 83</span> set_line(<span style="color: #0000ff;">char</span> *<span style="color: #000000;">line)<br/></span><span style="color: #008080;"> 84</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;"> 85</span> st_line =<span style="color: #000000;"> line;<br/></span><span style="color: #008080;"> 86</span> st_line_pos = <span style="color: #800080;">0</span><span style="color: #000000;">;<br/></span><span style="color: #008080;"> 87</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;"> 88</span> <br/><span style="color: #008080;"> 89</span> <span style="color: #0000ff;">#if</span> 1<br/><span style="color: #008080;"> 90</span> <span style="color: #0000ff;">void</span><br/><span style="color: #008080;"> 91</span> parse_line(<span style="color: #0000ff;">char</span> *<span style="color: #000000;">buf)<br/></span><span style="color: #008080;"> 92</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;"> 93</span> <span style="color: #000000;"> Token token;<br/></span><span style="color: #008080;"> 94</span> <br/><span style="color: #008080;"> 95</span> <span style="color: #000000;"> set_line(buf);<br/></span><span style="color: #008080;"> 96</span> <br/><span style="color: #008080;"> 97</span> <span style="color: #0000ff;">for</span><span style="color: #000000;"> (;;) {<br/></span><span style="color: #008080;"> 98</span> get_token(&amp;<span style="color: #000000;">token);<br/></span><span style="color: #008080;"> 99</span> <span style="color: #0000ff;">if</span> (token.kind ==<span style="color: #000000;"> END_OF_LINE_TOKEN) {<br/></span><span style="color: #008080;">100</span> <span style="color: #0000ff;">break</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">101</span> } <span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/></span><span style="color: #008080;">102</span> printf(<span style="color: #800000;">"</span><span style="color: #800000;">kind..%d, str..%s\n</span><span style="color: #800000;">"</span><span style="color: #000000;">, token.kind, token.str);<br/></span><span style="color: #008080;">103</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">104</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">105</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;">106</span> <br/><span style="color: #008080;">107</span> <span style="color: #0000ff;">int</span><br/><span style="color: #008080;">108</span> main(<span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> **<span style="color: #000000;">argv)<br/></span><span style="color: #008080;">109</span> <span style="color: #000000;">{<br/></span><span style="color: #008080;">110</span> <span style="color: #0000ff;">char</span> buf[<span style="color: #800080;">1024</span><span style="color: #000000;">];<br/></span><span style="color: #008080;">111</span> <br/><span style="color: #008080;">112</span> <span style="color: #0000ff;">while</span> (fgets(buf, <span style="color: #800080;">1024</span>, stdin) !=<span style="color: #000000;"> NULL) {<br/></span><span style="color: #008080;">113</span> <span style="color: #000000;"> parse_line(buf);<br/></span><span style="color: #008080;">114</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">115</span> <br/><span style="color: #008080;">116</span> <span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;<br/></span><span style="color: #008080;">117</span> <span style="color: #000000;">}<br/></span><span style="color: #008080;">118</span> <span style="color: #0000ff;">#endif</span></div></div><p><span style="font-size: 16px;">   token.h</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('3394bea6-aa76-4cb4-b8c3-ee5fc0534cc0')"><div id="cnblogs_code_open_3394bea6-aa76-4cb4-b8c3-ee5fc0534cc0" class="cnblogs_code_hide"><span style="color: #008080;"> 1</span> <span style="color: #000000;">#ifndef TOKEN_H_INCLUDED<br/></span><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">#define</span> TOKEN_H_INCLUDED<br/><span style="color: #008080;"> 3</span> <br/><span style="color: #008080;"> 4</span> typedef <span style="color: #0000ff;">enum</span><span style="color: #000000;"> {<br/></span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> BAD_TOKEN,<br/></span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> NUMBER_TOKEN,<br/></span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> ADD_OPERATOR_TOKEN,<br/></span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> SUB_OPERATOR_TOKEN,<br/></span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> MUL_OPERATOR_TOKEN,<br/></span><span style="color: #008080;">10</span> <span style="color: #000000;"> DIV_OPERATOR_TOKEN,<br/></span><span style="color: #008080;">11</span> <span style="color: #000000;"> END_OF_LINE_TOKEN<br/></span><span style="color: #008080;">12</span> <span style="color: #000000;">} TokenKind;<br/></span><span style="color: #008080;">13</span> <br/><span style="color: #008080;">14</span> <span style="color: #0000ff;">#define</span> MAX_TOKEN_SIZE (100)<br/><span style="color: #008080;">15</span> <br/><span style="color: #008080;">16</span> typedef <span style="color: #0000ff;">struct</span><span style="color: #000000;"> {<br/></span><span style="color: #008080;">17</span> <span style="color: #000000;"> TokenKind kind;<br/></span><span style="color: #008080;">18</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> value;<br/></span><span style="color: #008080;">19</span> <span style="color: #0000ff;">char</span><span style="color: #000000;"> str[MAX_TOKEN_SIZE];<br/></span><span style="color: #008080;">20</span> <span style="color: #000000;">} Token;<br/></span><span style="color: #008080;">21</span> <br/><span style="color: #008080;">22</span> <span style="color: #0000ff;">void</span> set_line(<span style="color: #0000ff;">char</span> *<span style="color: #000000;">line);<br/></span><span style="color: #008080;">23</span> <span style="color: #0000ff;">void</span> get_token(Token *<span style="color: #000000;">token);<br/></span><span style="color: #008080;">24</span> <br/><span style="color: #008080;">25</span> <span style="color: #0000ff;">#endif</span> /* TOKEN_H_INCLUDED */</div></div><p><span style="font-size: 16px;">   上面使用的方法是DFA(确定有限状态自动机)</span></p><p><img src="http://images.cnitblog.com/i/485067/201407/252249154002128.jpg" alt="" /></p><p><span style="font-size: 16px;">    上面的图有些指向error的箭头没有标出,不过这个图就大概描述了这个过程。可以自己baidu一些状态机的知识。</span></p><p><span style="font-size: 16px;">    有了这两章的基础就可以自己写个分析器了(作用:以后写应用程序时,要给程序一个配置文件时,可以自己写个脚本进行解析,方便用户书写配置文件。不过现在都使用xml语法了,都还有解析的库呢。都不知道学了以后还有没有机会用到实际中呢)。不过循环和判断就还不能实现。书中后面有讲到,不过看到后面一些内容就有一些力不从心了。感觉难难哒!</span></p><p>&nbsp;</p><p>&nbsp;</p><p>    DFA:<a href="http://www.cnblogs.com/zhanghaiba/p/3569928.html">http://www.cnblogs.com/zhanghaiba/p/3569928.html</a></p><p>    本文地址:<a href="http://www.cnblogs.com/wunaozai/p/3869101.html">http://www.cnblogs.com/wunaozai/p/3869101.html</a></p><img src="http://counter.cnblogs.com/blog/rss/3869101" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/wunaozai/p/3869101.html" target="_blank">利用yacc和lex制作一个小的计算器</a>,转载请注明。</p>http://www.cnblogs.com/datacool/p/datacool_android_ui_design_2014.html安卓应用玩换肤.半透明图片的应用 - DataCool文章虽然没啥营养,但是我想说:麻麻再也不用担心我画不好界面了!喜欢看无码高清大图的码农注意了,让你一次看个够!2014-07-25T15:16:00Z2014-07-25T15:16:00ZDataCoolhttp://www.cnblogs.com/datacool/<style><!--.First {TEXT-ALIGN: left; PADDING-BOTTOM: 6px; MARGIN: 10px 0px; PADDING-LEFT: 20px; PADDING-RIGHT: 20px; FONT-FAMILY: 'Microsoft Yahei'; BACKGROUND: #55895b; COLOR: #fff; CLEAR: both; FONT-SIZE: 20px; PADDING-TOP: 6px; border-radius: 4px}.Second {PADDING-BOTTOM: 6px; MARGIN: 10px 0px; PADDING-LEFT: 20px; PADDING-RIGHT: 20px; FONT-FAMILY: 'Microsoft Yahei'; BACKGROUND: #93c8a2; COLOR: #fff; CLEAR: both; FONT-SIZE: 18px; PADDING-TOP: 6px; border-radius: 4px}.Third {PADDING-BOTTOM: 6px; MARGIN: 15px 0px; PADDING-LEFT: 20px; PADDING-RIGHT: 20px; FONT-FAMILY: 'Microsoft Yahei'; BACKGROUND: #c6efd2; COLOR: #999; CLEAR: both; FONT-SIZE: 16px; PADDING-TOP: 6px; border-radius: 4px}.note {PADDING-BOTTOM: 15px; MARGIN: 10px 0px; PADDING-LEFT: 60px; PADDING-RIGHT: 20px; FONT-FAMILY: 'Microsoft Yahei'; BACKGROUND: url(http://images.cnblogs.com/cnblogs_com/libaoheng/305804/o_yellow-pin.png) #fcfaa9 no-repeat 20px 0px; CLEAR: both; FONT-SIZE: 15px; PADDING-TOP: 15px; box-shadow: 0 0 8px #aaa}.demo {TEXT-ALIGN: left; PADDING-BOTTOM: 6px; PADDING-LEFT: 20px; PADDING-RIGHT: 20px; BACKGROUND: orange; COLOR: #fff; CLEAR: both; FONT-SIZE: 16px; OVERFLOW: auto; PADDING-TOP: 6px; border-radius: 4px}BLOCKQUOTE {BORDER-LEFT: #ccc 10px solid; PADDING-BOTTOM: 0.5em; MARGIN: 1.5em 10px; PADDING-LEFT: 10px; WIDTH: 90%; PADDING-RIGHT: 10px; BACKGROUND: #f9f9f9; COLOR: #888; PADDING-TOP: 0.5em}#MySignature {background-color: #F8F8EE;border: solid 1px #E8E7D0;box-shadow: 0 0 15px #aaa;padding: 10px;margin-bottom:10px;color: gray;}--></style><p class="note">不懂美工的码农真的伤不起吗,非也,看我如何弄出高大上的UI。</p><p>最讨厌那些纯文字分享安卓开发的文章,亲上个图就那么难么。万一不是我想要的效果你不是耽误我时间么。学习安卓也有一段时间了,最近终于要捣鼓出来一个公司即将商用的App出来了。看了无数文章和体验了无数同类应用之后,深深的迷茫。一边手握反编译神器,一边阅读着海量文章,到底怎么办呢,出活啊,急死我了,没有好的解决方案啊,后来总结一条稍微可以看到曙光的路子:找一个心水的应用反编译之,提取该App使用的资源来实现自己的业务。唉,经过一番好找,终于找到原型了。反编译之后出现惊喜,这个App没有混淆加密,还能看到源码。OK!走一个!翠花,上(无码)大图!</p><p>&nbsp;</p><h6 class="First">1、翠花,上(无码)大图!成品欣赏!</strong></p><p>&nbsp;</p><p><img src="http://images.cnitblog.com/i/124467/201407/252241099472704.png" alt="" width="800" height="600" /></p><p><img src="http://images.cnitblog.com/i/124467/201407/252242059326832.png" alt="" width="800" height="600" /></p><p><img src="http://images.cnitblog.com/i/124467/201407/252244010578761.png" alt="" width="800" height="600" /></p><p><img src="http://images.cnitblog.com/i/124467/201407/252246409479714.png" alt="" width="800" height="600" /></p><p><img src="http://images.cnitblog.com/i/124467/201407/252247369478072.png" alt="" width="800" height="600" /></p><p><img src="http://images.cnitblog.com/i/124467/201407/252248505887375.png" alt="" width="800" height="600" /></p><p><img src="http://images.cnitblog.com/i/124467/201407/252249354328441.png" alt="" width="800" height="600" /></p><p><img src="http://images.cnitblog.com/i/124467/201407/252250552609952.png" alt="" width="800" height="600" /></p><p><img src="http://images.cnitblog.com/i/124467/201407/252252094631385.png" alt="" width="800" height="600" /></p><p>&nbsp;</p><h6 class="First">2、亲你猜对了,这不是换肤,其实就是换一个背景图片而已。</strong></p><p>高大上在哪里?一句话,专业的美工就是不一样啊,半透明图片的运用那简直神啊,大家都知道图层一般有个"透明度"属性吧,这里就是用这个属性实现了半透明效果。代码嘛其实就很简单了,在不同的activity之间使用共享的全局变量,变换最顶层View的背景即可。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">String bgOptionValue = ShareUtils.getValue(sp, "background"<span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">if</span> (bgOptionValue != <span style="color: #0000ff;">null</span> &amp;&amp; bgOptionValue.length() &gt; 0<span style="color: #000000;">) {<br/> mainView.setBackgroundResource(Integer.parseInt(bgOptionValue));<br/> bgResourceID </span>=<span style="color: #000000;"> Integer.parseInt(bgOptionValue);<br/> } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br/> mainView.setBackgroundResource(R.drawable.bg_01);</span></div><p>资源文件揭秘:</p><p><img src="http://images.cnitblog.com/i/124467/201407/252308326043396.png" alt="" /></p><p>看看上图应该就明白了,只需要灵活的应用安卓的各种布局,将业务UI放在居中的位置,不仅可以实现自适应还可以实现最简单的换肤特效。由于这个应用暂定于在安卓Pad或者安卓的触摸屏一体机上使用,目前可以兼容7寸以上的PAD。文章虽然没啥营养,但是我想说:麻麻再也不用担心我画不好界面了!</p><img src="http://counter.cnblogs.com/blog/rss/3869157" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/datacool/p/datacool_android_ui_design_2014.html" target="_blank">安卓应用玩换肤.半透明图片的应用</a>,转载请注明。</p>http://www.cnblogs.com/jack-1900/p/3869152.html一个效果很华丽的仿桌面APP,却胜似Launcher - JackCho开发Android APP的同学是否对于Launcher实现的绚丽效果而痴迷呢?什么,连Android Launcher是什么都不知道。好吧,拿起侬的手机,在解锁后的首页界面上左右滑动滑动,体验体验,这个就是Launcher。Launcher其实也是一个APP,不过人家是系统级别的。虽然各个andr...2014-07-25T15:06:00Z2014-07-25T15:06:00ZJackChohttp://www.cnblogs.com/jack-1900/<p>开发Android APP的同学是否对于Launcher实现的绚丽效果而痴迷呢?什么,连Android Launcher是什么都不知道。好吧,拿起侬的手机,在解锁后的首页界面上左右滑动滑动,体验体验,这个就是Launcher。</p><p>Launcher其实也是一个APP,不过人家是系统级别的。虽然各个android手机厂商对Launcher的定制化程度比较高,但是为了避免用户使用的困惑,Launcher的操作和功能基本都差不多。下面简单介绍下Launcher桌面的几个共同特征。</p><p>1、分屏显示APP图标和名称</p><p>2、APP图标可以在当前屏幕中拖动,稍牛逼的可以跨屏拖动</p><p>3、在拖动过程中交换位置,出现一系列漂亮的位移动画</p><p>4、拖动结束后,Lancher会记住重新排列的位置</p><p>5、APP图标可以被删除,删除后,后面的图片会依次向前位移过去</p><p>6、横向滑动Launcher进行切屏,背景图片会联动起来</p><p>总结完毕,介绍那么多,都是为了今天的干货做衬托。今天十足的干货,分量极沉,沉甸甸压得我一天都不得空闲,只为挤出时间整理出实现的代码。下面介绍下今天干货相对于原生Launcher的优势。</p><p><strong>1、分屏数可以无限扩展,可以为一屏,也可以为10屏,同时也不用为OOM烦恼,滑动也相当的流畅</strong></p><p><strong>2、每个Item的图标可以为两张图片,一张Normal状态下显示,一张Press状态现实</strong></p><p><strong>3、动态设置每屏的行数和列数,示例代码使用的是4行2列,并且自动计算item的宽度和高度</strong></p><p><strong>4、动态设置Container的item总数,根据行数列数,自动计算页数</strong></p><p><strong>5、长按即可进入编辑模式,点击即可删除item;添加item也是相当的简单方便。</strong></p><p>下面看下静止的效果,想把玩一番的同学请去Github下载安装</p><p><img src="http://static.oschina.net/uploads/img/201407/24223150_l3ux.jpg" alt="" data-ke-src="http://static.oschina.net/uploads/img/201407/24223150_l3ux.jpg" /></p><p><strong>今天代码都不贴了,源码的注释写的很详细,相信阅读起来应该没有什么困难。对于喜欢研究Android特效的同学和业务上有这种需求的同学,相信今天的干货会帮助蛮大的。为了效果上的美观,我A了上个东家的几张图,希望大家不要商用,仅供学习交流之用。</strong></p><p>代码地址:<a href="https://github.com/JackCho/AndroidLauncher" target="_blank" data-ke-src="https://github.com/JackCho/AndroidLauncher">https://github.com/JackCho/AndroidLauncher</a></p><p>如果觉得对你有所帮助,欢迎大家订阅我的微信公众账号&mdash;&mdash;<strong>Android干货分享(ID:android_share)</strong>。下面是微信的二维码,为你提供及时高质的Android干货。</p><p><a href="http://static.oschina.net/uploads/img/201311/05215429_bAdq.jpg" target="_blank" data-ke-src="http://static.oschina.net/uploads/img/201311/05215429_bAdq.jpg"><img src="http://static.oschina.net/uploads/img/201311/05215429_bAdq.jpg" alt="" data-ke-src="http://static.oschina.net/uploads/img/201311/05215429_bAdq.jpg" /></a></p><img src="http://counter.cnblogs.com/blog/rss/3869152" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/jack-1900/p/3869152.html" target="_blank">一个效果很华丽的仿桌面APP,却胜似Launcher</a>,转载请注明。</p>http://www.cnblogs.com/zjfstudio/p/3869148.htmlHadoop学习笔记(3)??分布式环境搭建 - 烈火青春zjfHadoop学习笔记(3) ??分布式环境搭建 前面,我们已经在单机上把Hadoop运行起来了,但我们知道Hadoop支持分布式的,而它的优点就是在分布上突出的,所以我们得搭个环境模拟一下。 在这里,我们采用这样的策略来模拟环境,我们使用3台ubuntu机器,1台为作主机(master),另外2台....2014-07-25T15:02:00Z2014-07-25T15:02:00Z烈火青春zjfhttp://www.cnblogs.com/zjfstudio/<p style="text-align: center;"><span style="font-family: 宋体; font-size: 12pt;"><strong>Hadoop学习笔记(3) </strong></span></p><p style="text-align: center;"><span style="font-family: 宋体; font-size: 12pt;"><strong> &mdash;&mdash;分布式环境搭建 </strong></span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">前面,我们已经在单机上把Hadoop运行起来了,但我们知道Hadoop支持分布式的,而它的优点就是在分布上突出的,所以我们得搭个环境模拟一下。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在这里,我们采用这样的策略来模拟环境,我们使用3台ubuntu机器,1台为作主机(master),另外2台作为从机(slaver)。同时,这台主机,我们就用第一章中搭建好的环境来。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">我们采用与第一章中相似的步骤来操作: </span></p><ol style="margin-left: 45pt;"><li><div style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;"><strong>运行环境搭建 </strong></span></div></li></ol><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在前面,我们知道,运行hadoop是在linux上运行的。所以我们单机就在ubuntu上运行着。所以同样,2台从机,同样采用linux系统。为了节省资源,本人试验时用了2台centOS系统,而且是采用命令行的方式,没有用图形方式。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">系统中软件准备,第一章中我们准备了subversion ssh ant 和jdk。那在这里,从机上我们不要这么多了,我们不用再下载、编译代码了,从主机上复制就行。所以在从机上只需要安装ssh 和jdk这两个: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">先用 sudo apt-get install ssh这个命令,把SSH安装起来。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体;"><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注:在centOS中,使用yum install ssh。 </em></span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">java环境,可以在网上下载一个JDK安装包,如:jdk-6u24-linux-i586.bin </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">安装直接在目录下运行./jdk-6u24-linux-i586.bin即可。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">然后配置jdk目录: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">先进入安装目录 cd jdk-6u24-&hellip; </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">然后输入 PWD 就可以看到java安装目录,复制下来: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301089794025.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">命令行执行:sudo gedit /etc/profile </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在打开的文件里,追加: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">export JAVA_HOME=/home/administrator/hadoop/jdk1.6.0_27 //这里要写安装目录 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">export PATH=${JAVA_HOME}/bin:$PATH </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">执行source /etc/profile 立即生效 </span></p><p style="text-align: justify;">&nbsp;</p><ol style="margin-left: 45pt;"><li><div style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;"><strong>网络配置 </strong></span></div></li></ol><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">要想运行分布式环境,那这3台计算机(虚拟机)肯定是要联网才行。同时,三台之前也要畅通无阻。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">如果直接采用虚拟机,就比较方便了,默在虚拟机中都使用NAT联网方式即可: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301107607980.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">分别进入三个系统,用ifconfig命令,可以查到当前分配过来的IP地址: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301112139610.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">如上图中可以看到是10.0.0.11。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">如果发现没有eth0,也就是说网卡还没启用或分配好地址,则可以手动分配: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">ifconfig eth0 10.0.0.12 netmask 255.255.255.0 //设置eht0 的IP地址 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">route add default gw 10.0.0.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置网关 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在VMware中,怎么看到网关呢,可以在菜单 编辑-&gt;虚拟网络编辑器 中看到: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301119162996.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">网关一定要配置对,否则光IP地址后,机器之前互想ping不通的。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在配置好IP后,可以尝试ping一下网关和其他机器,看是否能通。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在这里,我们3台机IP为: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">主机 master : 10.0.0.10 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">从机1 salter1 :10.0.0.11 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">从机2 salter2 :10.0.0.12 </span></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">有了3台机器的IP地址,我们想,后面在配置中肯定会用到,但为了方便以后IP地址的变动,所以我们还是用另名吧。在window中,我们知道在C:\Windows\System32\driver\etc下,有个host文件,修改后,就可以将IP换成别名了。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在linux中,同样有这个文件,在/etc/hosts中。所以编辑一下: $vi /etc/hosts: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301122134438.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;文件保存后,就可以试一下ping master ping node1来代替IP地址了。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">这个操作需要在三个机器上都操作一下。 </span></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">现在网络了,为了后面操作,在所有部署运行hadoop的机器上,都必须使用相同的帐号。所以需要在2台从机上创建一个与主机一样的帐号、密码: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">比如都用zjf帐号: $user add zjf 设置密码: $passwd zjf 进入该帐号: $su zjf </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">有可能机器上会有防火墙,影响后面的远程,所以可以先关一下: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">$</span><span style="color: #333333; font-family: Arial; font-size: 10pt;"> service iptables stop </span></p><p style="text-align: justify;">&nbsp;</p><ol style="margin-left: 45pt;"><li><div style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;"><strong>配置SSH </strong></span></div></li></ol><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">第1章中我们了解了SSH的功能,在这里就可真正派用处了。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">我们在master机中,用ssh试一下连接node1: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301125729394.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">可以看到,需要输入密码才能够进入。远程启动所有从机时,一个个输入密码,也不是个好事,得配置下: </span></p><ol style="margin-left: 48pt;"><li><div style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在从机node1中先实现自己登陆自己时不要输入密码。 </span></div><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">这个在第1章中已经描述。这里就不多述了。结果就是: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301129632810.png" alt="" /></p></li><li><div style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">让主结点(master)能通过SSH免密码登录两个子结点(slave) </span></div><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">为了实现这个功能,两个slave结点的公钥文件中必须要包含主结点的公钥信息,这样当master就可以顺利安全地访问这两个slave结点了。操作过程如下: </span></p></li></ol><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301134327264.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;$cd ~/.ssh </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;$scp <a href="mailto:zjf@master:~/.ssh/id_dsa.pub%20./master_dsa.pub">zjf@master:~/.ssh/id_dsa.pub ./master_dsa.pub</a> </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;$cat master_dsa.pub &gt;&gt; authorized_keys </span></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">好了,配置完后,回到master机器中,再来试一下ssh node1: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301146827549.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">OK,成功进入,没有要输入密码。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">同样,把node2也安这个方式操作一下。 </span></p><p style="text-align: justify;">&nbsp;</p><ol style="margin-left: 45pt;"><li><div style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;"><strong>配置hadoop </strong></span></div></li></ol><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在第一章配置基础上,我们需要增加两项配置: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301150729964.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在conf文件夹下,找到masters文件,编辑,在里面输入master后保存: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301155256892.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在同文件夹下,找到slaves,编辑,在里面输入node1 node2后保存: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301159793820.png" alt="" /></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">打开conf下core-site.xml: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301167757177.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">里面的localhost换成master。 </span></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">打开conf下的marped-site.xml: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301174477805.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">同样,也是里面的localhost换成master。 </span></p><p style="text-align: justify;">&nbsp;</p><ol style="margin-left: 45pt;"><li><div style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;"><strong>复制hadoop包 </strong></span></div></li></ol><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">前面,在一台机器上部署时,我们的hadoop包是通过SVN下载了源码,然后再用ant编译出来的,但在这里,从机上就不用这么麻烦了,我们可以从主机上复制过去。如何复制呢? 远程登陆我们用SSH,远程复制就用SCP。在复制前要注意,我们在主机中hadoop存放在什么位置,在从机中也要存放在该位置才行。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">比如,在主机中,我们存放于test下,所以在2台node上,都创建一下test文件夹。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">然后在主机上执行:scp -r hadoop-0.20.2/ node1:~/test 然后会看到刷屏,表示在复制了。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">同样执行: scp -r hadoop-0.20.2/ node2:~/test </span></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">好了,现在两台从机上也都有了hadoop包了。 </span></p><p style="text-align: justify;">&nbsp;</p><ol style="margin-left: 45pt;"><li><div style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;"><strong>运行 </strong></span></div></li></ol><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在主机上,进入hadoop-0.20.2目录,运行bin/start-all.sh,即可以启动整个分布式系统了。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">然后在主机上运行jps: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301177296019.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在从机上运行jps: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301179004733.png" alt="" /></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">在主服务器上打开 <a href="http://localhost:50070">http://localhost:50070</a>,可以看到: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301184947619.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">有两个活动的结点,点进去,可以看到: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301191049032.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">点下面的结点可以查看详细,如果点开页面打不开,则有可能是机器防火墙阻止了。 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">可以进入相应机器,执行 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">$</span><span style="color: #333333; font-family: Arial; font-size: 10pt;"> service iptables stop </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">来关闭防火墙。 </span></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">我们可以尝试上传一下文件: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">$</span><span style="font-family: 宋体; font-size: 12pt;">bin/hadoop fs -put ~/Tool/eclipse-SDK-3.7.1-linux-gtk.tar.gz test1.tar.gz </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">可以看到: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301197447903.png" alt="" /></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">再上传一下文件: </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">$</span><span style="font-family: 宋体; font-size: 12pt;">bin/hadoop fs -put ~/Tool/eclipse-SDK-3.7.1-linux-gtk.tar.gz test2.tar.gz </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">可以看到: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301202449817.png" alt="" /></p><p style="text-align: justify;">&nbsp;</p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">但发现不平衡,都跑一台上了。所以可以执行命令 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">$</span><span style="font-family: 宋体; font-size: 12pt;">bin/hadoop balancer -threshold 1 </span></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">这样,再来看: </span></p><p style="text-align: justify;"><img src="http://images.cnitblog.com/blog/76595/201407/252301207754488.png" alt="" /></p><p style="text-align: justify;"><span style="font-family: 宋体; font-size: 12pt;">平衡了。 </span></p><p style="text-align: justify;">&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3869148" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/zjfstudio/p/3869148.html" target="_blank">Hadoop学习笔记(3)??分布式环境搭建</a>,转载请注明。</p>http://www.cnblogs.com/52cik/p/js-json-stringify-escape.html浅谈 JSON 那些被转义的字符们 - 乱码.其实,之前我一直以为 JSON 会把 ASCII 可显示字符以外的统统转义为 Unicode,直到有一次我用 JSON.stringify 才发现,其实是 PHP 为我们想的太周到了。我以前是一位 phper,所以处理 json 只要 json_encode 就可以把数组转为 json 数据了,非常...2014-07-25T14:46:00Z2014-07-25T14:46:00Z乱码.http://www.cnblogs.com/52cik/<p class="nop"><img class="nop" src="http://files.cnblogs.com/52cik/caption.gif" alt="" border="0" /></p><p>其实,之前我一直以为 JSON 会把 ASCII 可显示字符以外的统统转义为 Unicode,<br />直到有一次我用 JSON.<span style="color: #3366ff;">stringify</span> 才发现,其实是 PHP 为我们想的太周到了。</p><p>我以前是一位 phper,所以处理 json 只要 <span style="color: #3366ff;">json_encode</span> 就可以把数组转为 json 数据了,非常方便。<br /><img src="http://images.cnitblog.com/i/477954/201407/252240526354958.jpg" alt="" /><br />可以看到,默认就是把所有 ASCII 可显示字符以外的统统转义为 Unicode。</p><p>这样做有什么好处呢?<br />大家在调用 jsonp 接口或者调用js文件的时候,由于文件编码不同导致的乱码问题,应该不会陌生吧。<br />如果你的文件出现了非英文字符,如果调用时文件编码不一致,则会出现乱码情况。<br />很多新手朋友应该都纠结过这种问题吧。</p><p>但是如果把那些字符转义为 Unicode 之后,无论文件编码是否一致,都不会出现乱码。<br />这就是为什么 PHP 会默认编码为 Unicode 的原因,她为我们想的太周到了。</p><p>当然如果你非要直接显示那些字符,也是OK的,第二个参数加上 <span style="color: #3366ff;">JSON_UNESCAPED_UNICODE</span> 即可。<br />但是这个参数 <span style="color: #ff0000;">PHP 5.4.0</span> 才开始支持。</p><p>那么 JSON.<span style="color: #3366ff;">stringify</span> 会转义哪些呢?<br />在 <a href="https://github.com/douglascrockford/JSON-js/blob/master/json2.js#L351" target="_blank">json2.js</a> 第 351 行可以看到这个正则。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;</div><p>也就是说 JSON 只会转义这部分字符为 unicode,我们来简单测试下吧。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">console.log( JSON.stringify("\x00 \x0a") );</div><p>点运行后,可以看到 <span style="color: #3366ff;">\x00</span> 被转义为 <span style="color: #3366ff;">\u0000</span> 而 <span style="color: #3366ff;">\x0a</span> 却被专为了 <span style="color: #3366ff;">\n</span><br />像 <span style="color: #3366ff;">\n</span> 这些特殊字符的转换在刚才那个正则下面就可以看到了。</p><p>但是你测试字符 <span style="color: #3366ff;">\ufeff</span> 的时候会发现 firefox 和 chrome 根本没转义。<br />确实,,好像只有 json2 为我们转义了。</p><p>为什么原生 JSON.<span style="color: #3366ff;">stringify</span> 这么多字符都没转义,难道他就没为我们考虑兼容问题么?<br />其实我觉得,这个问题可以不要考虑,因为你不会直用静态的页面为其他站点提供接口之类的。<br />往往只是自己内部用而已,就算提交给后台,一个项目下编码也是一样的,所以内部不需要考虑那些兼容问题。<br />就好比在自己老家,难道你要普通话或英文跟他们交流么?<br />直接用方言交流才更加流畅。</p><p>当然这个只是我个人观点,也不知道写js引擎的大神是怎么想的。</p><p>我们来遍历下原生 JSON 对 \u000-\uffff 这些字符的转义情况吧。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">for (var i = 0, str = '', arr = []; i &lt; 0xffff; i++) {<br/> str = JSON.stringify(String.fromCharCode(i));<br/> str.indexOf("\\") &gt; -1 &amp;&amp; arr.push(str);<br/>}<br/>console.log(arr.join(", "));</div><p>我的 chrome 34 得到的结果是</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">["\u0000", "\u0001", "\u0002", "\u0003", "\u0004", "\u0005", "\u0006", "\u0007", "\b", "\t", "\n", "\u000b", "\f", "\r", "\u000e", "\u000f", "\u0010", "\u0011", "\u0012", "\u0013", "\u0014", "\u0015", "\u0016", "\u0017", "\u0018", "\u0019", "\u001a", "\u001b", "\u001c", "\u001d", "\u001e", "\u001f", "\"", "\\"];</div><p>好了,今天的分享就这些了。</p><img src="http://counter.cnblogs.com/blog/rss/3869124" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/52cik/p/js-json-stringify-escape.html" target="_blank">浅谈 JSON 那些被转义的字符们</a>,转载请注明。</p>http://www.cnblogs.com/stoneniqiu/p/3869098.html罗盘 - stoneniqiu有时候内心迷茫,如同窒息,想抽烟,想冲撞。甚至有些怀疑,自己是否进错了空间,眼前四壁,何以突破?我没有太大的理想,只想凭自己的能力,可以让爱的人去想去的地方,过着简单充实的生活,但持续的追逐在人生路上,扶手莞尔,用心经营。工作上热情但算不上痴迷,起码会保持自己的节奏。我是承认,人的价值观很不一...2014-07-25T14:31:00Z2014-07-25T14:31:00Zstoneniqiuhttp://www.cnblogs.com/stoneniqiu/<p>&nbsp; &nbsp; &nbsp; 有时候内心迷茫,如同窒息,想抽烟,想冲撞。甚至有些怀疑,自己是否进错了空间,眼前四壁,何以突破?<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我没有太大的理想,只想凭自己的能力,可以让爱的人去想去的地方,过着简单充实的生活,但持续的追逐在人生路上,扶手莞尔,用心经营。工作上热情但算不上痴迷,起码会保持自己的节奏。我是承认,人的价值观很不一样,简单的说有的聊,没得聊。平行的世界,有太多平行的空间,难有交集。但这又怎么样,这就是宇宙,这就是世界的样子。你安好不安好,它就在那。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这两天想着内圣外王这个词,一个人有自己的态度,但他不会要求别人也和他遵守一样的准则,相反他会&ldquo;伪装&rdquo;的和大家一样。也就是严于律己,宽于律人,照样和各种小伙伴愉快的玩耍。罗胖说(至少他说过)现在的社会,不是看一个人能有多牛逼,而是看这个人能调动多少资源来帮他。这也是互联网思维吧。你有多少有用的&ldquo;链接&rdquo;来给你或者给别人带来价值,从而你的价值也提高了。<br />&nbsp;&nbsp;&nbsp;&nbsp;我不是一个聪明的人,倒是有些笨,学一些东西往往要重复很多遍,对于别人的好的为人处世不能很快很好的吸收。思想上也容易疲软,置身原野,四顾茫茫的情况时而有之,不像那些传记中的人物,比如曾国藩,丁忧夺情之后的他,完全不是以前的他。一个人蜕变,离不开对苦难和挫折的细细品尝,对自己,对世界的深度反思。而我们当然不是什么圣人,也没有什么汽车人的能量块,路上走走停停,曲曲折折,就是这个轨迹,方向可以调整,但态度始终如一。<br />&nbsp;&nbsp;&nbsp;困顿之时,一个人去跑步,摘下眼镜,世界关在模糊的夜色之中,行色匆匆,只看得见脚下的路,听到自己的心跳和踏实的脚步声,&ldquo;hold on,hold on...&rdquo;,体力耗尽,到达终点,却难得释然。回去翻翻大牛们的博客,看着人家写过的文章读过的书,咽下羡慕的口水,还等什么呢。</p><img src="http://counter.cnblogs.com/blog/rss/3869098" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/stoneniqiu/p/3869098.html" target="_blank">罗盘</a>,转载请注明。</p>http://www.cnblogs.com/dooroo/p/3869096.html[WPF]绑定到界面的数组不支持调度线程以外对其更改的办法 - 小颗豆不支持从调度程序线程以外的线程对其SourceCollection进行的更改,数据绑定,线程更改2014-07-25T14:30:00Z2014-07-25T14:30:00Z小颗豆http://www.cnblogs.com/dooroo/<p>[原]WPF编程经常遇到一个问题:</p><p>&nbsp; &nbsp; &nbsp; 某个数组己绑定到主界面某控件中,然后在后台程序中需要对数组增(减)数据,然后程序就会报错,</p><p>程序提示:该类型的CollectionView 不支持从调度程序线程以外的线程对其SourceCollection进行的更改。</p><p>如下图所示:</p><p><img src="http://images.cnitblog.com/i/296541/201407/251758553699612.jpg" alt="" /></p><p>既然不能这样操作,就得想一个办法来解决,现在先把把出现错误的程序全部列出来,然后再来根据解决办法进行修改,</p><p>本测试程序先建一个学生类:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('6718f50d-a6a8-427b-95b0-219464e04e8c')"><div id="cnblogs_code_open_6718f50d-a6a8-427b-95b0-219464e04e8c" class="cnblogs_code_hide"><span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.ComponentModel;<br/><br/></span><span style="color: #0000ff;">namespace</span><span style="color: #000000;"> WPF_test<br/>{<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> student : INotifyPropertyChanged <br/> {<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">定义数据更改事件通知和更改的方法</span><br/> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span><span style="color: #000000;"> PropertyChangedEventHandler PropertyChanged;<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> up(<span style="color: #0000ff;">string</span><span style="color: #000000;"> s)<br/> {<br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.PropertyChanged != <span style="color: #0000ff;">null</span><span style="color: #000000;">)<br/> {<br/> PropertyChanged(</span><span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span><span style="color: #000000;"> PropertyChangedEventArgs(s));<br/> }<br/> }<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">姓名</span><br/> <span style="color: #0000ff;">string</span><span style="color: #000000;"> _name;<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> name<br/> {<br/> </span><span style="color: #0000ff;">get</span> { <span style="color: #0000ff;">return</span><span style="color: #000000;"> _name; }<br/> </span><span style="color: #0000ff;">set</span> { _name = value; up(<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">); }<br/> }<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">学号</span><br/> <span style="color: #0000ff;">string</span><span style="color: #000000;"> _id;<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span><span style="color: #000000;"> id<br/> {<br/> </span><span style="color: #0000ff;">get</span> { <span style="color: #0000ff;">return</span><span style="color: #000000;"> _id; }<br/> </span><span style="color: #0000ff;">set</span> { _id = value; up(<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">); }<br/> }<br/><br/> </span><span style="color: #0000ff;">public</span> student(<span style="color: #0000ff;">string</span> _id, <span style="color: #0000ff;">string</span><span style="color: #000000;"> _name)<br/> {<br/> id </span>=<span style="color: #000000;"> _id;<br/> name </span>=<span style="color: #000000;"> _name;<br/> }<br/> </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> student()<br/> { }<br/> <br/> }<br/>}</span></div></div><p>主窗口xaml代码(将students数组绑定到主界面中):</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('6edb87bf-4873-42f7-a9e4-ea8c2863101c')"><div id="cnblogs_code_open_6edb87bf-4873-42f7-a9e4-ea8c2863101c" class="cnblogs_code_hide">&lt;Window x:Class=<span style="color: #800000;">"</span><span style="color: #800000;">WPF_test.MainWindow</span><span style="color: #800000;">"</span><span style="color: #000000;"><br/> xmlns</span>=<span style="color: #800000;">"</span><span style="color: #800000;">http://schemas.microsoft.com/winfx/2006/xaml/presentation</span><span style="color: #800000;">"</span><span style="color: #000000;"><br/> xmlns:x</span>=<span style="color: #800000;">"</span><span style="color: #800000;">http://schemas.microsoft.com/winfx/2006/xaml</span><span style="color: #800000;">"</span><span style="color: #000000;"><br/> xmlns:zz</span>=<span style="color: #800000;">"</span><span style="color: #800000;">clr-namespace:WPF_test</span><span style="color: #800000;">"</span><span style="color: #000000;"><br/> Title</span>=<span style="color: #800000;">"</span><span style="color: #800000;">MainWindow</span><span style="color: #800000;">"</span> Height=<span style="color: #800000;">"</span><span style="color: #800000;">350</span><span style="color: #800000;">"</span> Width=<span style="color: #800000;">"</span><span style="color: #800000;">525</span><span style="color: #800000;">"</span> Loaded=<span style="color: #800000;">"</span><span style="color: #800000;">Window_Loaded</span><span style="color: #800000;">"</span> &gt;<br/> &lt;Window.Resources &gt;<br/> &lt;zz:VisibilityConverter x:Key=<span style="color: #800000;">"</span><span style="color: #800000;">VisibilityConverter</span><span style="color: #800000;">"</span>/&gt;<br/> &lt;/Window.Resources&gt;<br/> &lt;DockPanel &gt;<br/> &lt;StackPanel Orientation=<span style="color: #800000;">"</span><span style="color: #800000;">Horizontal</span><span style="color: #800000;">"</span> DockPanel.Dock=<span style="color: #800000;">"</span><span style="color: #800000;">Bottom</span><span style="color: #800000;">"</span> HorizontalAlignment=<span style="color: #800000;">"</span><span style="color: #800000;">Center</span><span style="color: #800000;">"</span> Margin=<span style="color: #800000;">"</span><span style="color: #800000;">0 10 </span><span style="color: #800000;">"</span>&gt;<br/> &lt;Button Content=<span style="color: #800000;">"</span><span style="color: #800000;">出错测试</span><span style="color: #800000;">"</span> Margin=<span style="color: #800000;">"</span><span style="color: #800000;">20 0</span><span style="color: #800000;">"</span> Click=<span style="color: #800000;">"</span><span style="color: #800000;">Button_Click</span><span style="color: #800000;">"</span> /&gt;<br/> &lt;Button Content=<span style="color: #800000;">"</span><span style="color: #800000;">正确测试</span><span style="color: #800000;">"</span> Margin=<span style="color: #800000;">"</span><span style="color: #800000;">20 0</span><span style="color: #800000;">"</span> Click=<span style="color: #800000;">"</span><span style="color: #800000;">Button_Click_1</span><span style="color: #800000;">"</span> /&gt;<br/> &lt;/StackPanel&gt;<br/> &lt;Grid&gt;<br/> &lt;!-- 顶层等待动画--&gt;<br/> &lt;Grid Name=<span style="color: #800000;">"</span><span style="color: #800000;">g1</span><span style="color: #800000;">"</span> Panel.ZIndex=<span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span> Visibility=<span style="color: #800000;">"</span><span style="color: #800000;">{Binding isWorking, Converter={StaticResource VisibilityConverter}}</span><span style="color: #800000;">"</span>&gt;<br/> &lt;Border Background=<span style="color: #800000;">"</span><span style="color: #800000;">Black</span><span style="color: #800000;">"</span> Height=<span style="color: #800000;">"</span><span style="color: #800000;">100</span><span style="color: #800000;">"</span> BorderBrush=<span style="color: #800000;">"</span><span style="color: #800000;">Gold</span><span style="color: #800000;">"</span> Opacity=<span style="color: #800000;">"</span><span style="color: #800000;">0.7</span><span style="color: #800000;">"</span> BorderThickness=<span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span>&gt;<br/> &lt;StackPanel &gt;<br/> &lt;TextBlock Text=<span style="color: #800000;">"</span><span style="color: #800000;">请稍等</span><span style="color: #800000;">"</span> HorizontalAlignment=<span style="color: #800000;">"</span><span style="color: #800000;">Center</span><span style="color: #800000;">"</span> Foreground=<span style="color: #800000;">"</span><span style="color: #800000;">White</span><span style="color: #800000;">"</span> Margin=<span style="color: #800000;">"</span><span style="color: #800000;">0 10 0 0</span><span style="color: #800000;">"</span>&gt;&lt;/TextBlock&gt;<br/> &lt;ProgressBar IsIndeterminate=<span style="color: #800000;">"</span><span style="color: #800000;">True</span><span style="color: #800000;">"</span> Height=<span style="color: #800000;">"</span><span style="color: #800000;">25</span><span style="color: #800000;">"</span> Margin=<span style="color: #800000;">"</span><span style="color: #800000;">20</span><span style="color: #800000;">"</span>&gt;&lt;/ProgressBar&gt;<br/> &lt;/StackPanel&gt;<br/> &lt;/Border&gt;<br/> &lt;/Grid&gt;<br/> &lt;!-- 底层数据显示--&gt;<br/> &lt;ListView Name=<span style="color: #800000;">"</span><span style="color: #800000;">listview1</span><span style="color: #800000;">"</span>&gt;<br/> &lt;ListView.View&gt;<br/> &lt;GridView &gt;<br/> &lt;GridViewColumn Header=<span style="color: #800000;">"</span><span style="color: #800000;">学号</span><span style="color: #800000;">"</span> Width=<span style="color: #800000;">"</span><span style="color: #800000;">80</span><span style="color: #800000;">"</span> DisplayMemberBinding=<span style="color: #800000;">"</span><span style="color: #800000;">{Binding id}</span><span style="color: #800000;">"</span>/&gt;<br/> &lt;GridViewColumn Header=<span style="color: #800000;">"</span><span style="color: #800000;">姓名</span><span style="color: #800000;">"</span> Width=<span style="color: #800000;">"</span><span style="color: #800000;">150</span><span style="color: #800000;">"</span> DisplayMemberBinding=<span style="color: #800000;">"</span><span style="color: #800000;">{Binding name}</span><span style="color: #800000;">"</span>/&gt;<br/> &lt;/GridView&gt;<br/> &lt;/ListView.View&gt;<br/> &lt;/ListView&gt;<br/> &lt;/Grid&gt;<br/> <br/> &lt;/DockPanel&gt;<br/>&lt;/Window&gt;</div></div><p>等待动画类代码:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('21df79bb-dd7f-4acd-a2ab-a8c905c6f0cd')"><div id="cnblogs_code_open_21df79bb-dd7f-4acd-a2ab-a8c905c6f0cd" class="cnblogs_code_hide"><span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.ComponentModel;<br/><br/></span><span style="color: #0000ff;">namespace</span><span style="color: #000000;"> WPF_test<br/>{<br/> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> witeMe:INotifyPropertyChanged <br/> {<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span><span style="color: #000000;"> PropertyChangedEventHandler PropertyChanged;<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> up(<span style="color: #0000ff;">string</span><span style="color: #000000;"> s)<br/> {<br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.PropertyChanged != <span style="color: #0000ff;">null</span><span style="color: #000000;">)<br/> {<br/> PropertyChanged(</span><span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span><span style="color: #000000;"> PropertyChangedEventArgs(s));<br/> }<br/> }<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">工作提示状态</span><br/> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">bool</span> _isWorking = <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span><span style="color: #000000;"> isWorking<br/> {<br/> </span><span style="color: #0000ff;">get</span> { <span style="color: #0000ff;">return</span><span style="color: #000000;"> _isWorking; }<br/> </span><span style="color: #0000ff;">set</span> { _isWorking = value; up(<span style="color: #800000;">"</span><span style="color: #800000;">isWorking</span><span style="color: #800000;">"</span><span style="color: #000000;">); }<br/> }<br/> }<br/>}</span></div></div><p>主窗口核心代码:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('e5913b6f-3f1e-47e0-8b73-1e7a1f81fe05')"><div id="cnblogs_code_open_e5913b6f-3f1e-47e0-8b73-1e7a1f81fe05" class="cnblogs_code_hide"><span style="color: #0000ff;">using</span><span style="color: #000000;"> System;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.Generic;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Linq;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Text;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Windows;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Windows.Controls;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Windows.Data;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Windows.Shapes;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Collections.ObjectModel;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading;<br/></span><span style="color: #0000ff;">using</span><span style="color: #000000;"> System.Threading.Tasks;<br/><br/><br/></span><span style="color: #0000ff;">namespace</span><span style="color: #000000;"> WPF_test<br/>{<br/> </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;summary&gt;</span><br/> <span style="color: #808080;">///</span><span style="color: #008000;"> MainWindow.xaml 的交互逻辑<br/> </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;/summary&gt;</span><br/> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> MainWindow : Window<br/> {<br/> </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> MainWindow()<br/> {<br/> InitializeComponent();<br/> }<br/><br/> ObservableCollection</span>&lt;student&gt; students = <span style="color: #0000ff;">new</span> ObservableCollection&lt;student&gt;<span style="color: #000000;">();<br/> witeMe wm </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> witeMe();<br/><br/> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> Window_Loaded(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, RoutedEventArgs e)<br/> {<br/> students.Add(</span><span style="color: #0000ff;">new</span> student(<span style="color: #800000;">"</span><span style="color: #800000;">1号</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">张三</span><span style="color: #800000;">"</span><span style="color: #000000;">));<br/> students.Add(</span><span style="color: #0000ff;">new</span> student(<span style="color: #800000;">"</span><span style="color: #800000;">2号</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">李四</span><span style="color: #800000;">"</span><span style="color: #000000;">));<br/> listview1.ItemsSource </span>=<span style="color: #000000;"> students;<br/> g1.DataContext </span>=<span style="color: #000000;"> wm;<br/> }<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">出错测试</span><br/> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> Button_Click(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, RoutedEventArgs e)<br/> {<br/> students.Clear();<br/> Task tk </span>= <span style="color: #0000ff;">new</span> Task(() =&gt;<span style="color: #000000;"><br/> {<br/> Action</span>&lt;student, <span style="color: #0000ff;">bool</span>&gt; ac1 = (x, y) =&gt;<span style="color: #000000;"> students.Add(x);<br/> createStudents(ac1);<br/> });<br/> tk.Start();<br/> tk.ContinueWith((t) </span>=&gt; MessageBox.Show(<span style="color: #800000;">"</span><span style="color: #800000;">结束</span><span style="color: #800000;">"</span><span style="color: #000000;">));<br/> }<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">正确测试</span><br/> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> Button_Click_1(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, RoutedEventArgs e)<br/> {<br/> students.Clear();<br/> wm.isWorking </span>= <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/><br/> Task tk </span>= <span style="color: #0000ff;">new</span> Task(() =&gt;<span style="color: #000000;"><br/> {<br/><br/> Action</span>&lt;student, <span style="color: #0000ff;">bool</span>&gt; ac2 = (x, y) =&gt;<span style="color: #000000;"> addData(x, y);<br/> createStudents(ac2);<br/> });<br/> tk.Start();<br/> }<br/><br/> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> addData(student s, <span style="color: #0000ff;">bool</span><span style="color: #000000;"> k)<br/> {<br/> ThreadPool.QueueUserWorkItem(</span><span style="color: #0000ff;">delegate</span><span style="color: #000000;"><br/> {<br/> </span><span style="color: #0000ff;">this</span>.Dispatcher.Invoke(<span style="color: #0000ff;">new</span> Action(() =&gt;<span style="color: #000000;"><br/> {<br/> students.Add(s);<br/> </span><span style="color: #0000ff;">if</span> (k == <span style="color: #0000ff;">true</span><span style="color: #000000;">)<br/> wm.isWorking </span>= <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> students.Insert(0, s);</span><span style="color: #008000;">//</span><span style="color: #008000;">这样也会很卡<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">listview1.ScrollIntoView(s);</span><span style="color: #008000;">//</span><span style="color: #008000;">这个不行,大数据时真会卡死了</span><br/> }), <span style="color: #0000ff;">null</span><span style="color: #000000;">);<br/> });<br/> }<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">创建学生数组</span><br/> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> createStudents(Action&lt;student, <span style="color: #0000ff;">bool</span>&gt;<span style="color: #000000;"> _ac)<br/> {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = <span style="color: #800080;">0</span>; i &lt; <span style="color: #800080;">100000</span>; i++<span style="color: #000000;">)<br/> {<br/> student s </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> student();<br/> s.id </span>= (i + <span style="color: #800080;">1</span><span style="color: #000000;">).ToString();<br/> s.name </span>= <span style="color: #800000;">"</span><span style="color: #800000;">小颗豆</span><span style="color: #800000;">"</span> + (i + <span style="color: #800080;">1</span><span style="color: #000000;">).ToString();<br/> </span><span style="color: #0000ff;">if</span> (i &lt; <span style="color: #800080;">99999</span><span style="color: #000000;">)<br/> _ac(s, </span><span style="color: #0000ff;">false</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br/> _ac(s, </span><span style="color: #0000ff;">true</span><span style="color: #000000;">);<br/> }<br/><br/> }<br/><br/><br/> }<br/>}</span></div></div><p>程序运行时:点击"错误测试"就会出现文章前边的错误图示,点击"正确测试"出现下图,一切正常:</p><p><img src="http://images.cnitblog.com/i/296541/201407/252117171194961.jpg" alt="" /></p><p>正确测试时绑定的数组边修改,画面边显示,而且主窗口也没有卡死,鼠标也能拖动窗口,基本能达到目的了,下面分析一下代码是如何解决的:</p><p> //创建学生数组<br /> private void createStudents(Action&lt;student, bool&gt; _ac)<br /> {<br /> for (int i = 0; i &lt; 100000; i++)<br /> {<br /> student s = new student();<br /> s.id = (i + 1).ToString();<br /> s.name = "小颗豆" + (i + 1).ToString();<br /> if (i &lt; 99999)<br /> _ac(s, false);<br /> else<br /> _ac(s, true);<br /> }</p><p> }</p><p>在以上代码中每增加一个学生成员到数组中都是通过_ac(s,bool)委托进行的,</p><p>委托的定义是在异步线程中定义好的.即是ac2</p><p> Task tk = new Task(() =&gt;<br /> {</p><p> Action&lt;student, bool&gt; ac2 = (x, y) =&gt; addData(x, y);<br /> createStudents(ac2);<br /> });<br /> tk.Start();</p><p>异步Task里,先定义了委托,每增加一个数组成员时委托addData方法在主界面调用者线程中由线程池去操作即可解决外线程不能更改数组的问题:</p><p> private void addData(student s, bool k)<br /> {<br /> ThreadPool.QueueUserWorkItem(delegate<br /> {<br /> this.Dispatcher.Invoke(new Action(() =&gt;<br /> {<br /> students.Add(s);<br /> if (k == true)<br /> wm.isWorking = false;<br /> // students.Insert(0, s);//这样会很卡,如果数据量小时则会显得很流畅</p><p>//listview1.ScrollIntoView(s);//这个不行,小数据无所谓,大数据时真会卡死界面了<br /> }), null);<br /> });<br /> }</p><p>上边的代码中,</p><p>this.Dispatcher.Invoke(new Action(() =&gt;<br />{<br />students.Add(s);<br />}),null);这里是关键的解决办法,主窗体是主线程创建的,每个线程都有一个唯一的调度员,我们的工作就是命令调度员去做相应的工作,这里我们就相当于命令主窗体的线程调度员去增加数组成员,这样做线程是安全的,不会再有错误提示。</p><p>以上是本人测试的例子,不足之处请批评指正,高手请飘过。</p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3869096" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/dooroo/p/3869096.html" target="_blank">[WPF]绑定到界面的数组不支持调度线程以外对其更改的办法</a>,转载请注明。</p>http://www.cnblogs.com/qigang/p/3866810.htmlJS中图片飞飞效果 - 恋那片海当鼠标在界面上移动的时候,后面有一连串的图片跟随者一起飘动,效果如下:实现的基本思想:准备五个img标签,为了方便控制都放在一个div里面,设置div的定位方式为 fixed,设置成这中定位方式主要是为了解决在页面出现滚动条的情况下,图片还能够跟随鼠标移动。然后再鼠标移动的时候,延时给每一个图片设置...2014-07-25T14:05:00Z2014-07-25T14:05:00Z恋那片海http://www.cnblogs.com/qigang/<p><span style="font-size: 15px;">当鼠标在界面上移动的时候,后面有一连串的图片跟随者一起飘动,效果如下:</span></p><p><span style="font-size: 15px;"><img src="http://images.cnitblog.com/i/506342/201407/242341110883355.jpg" alt="" /><img src="http://images.cnitblog.com/i/506342/201407/242341244795830.jpg" alt="" /></span></p><p><span style="font-size: 15px;">&nbsp;</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;<strong>实现的基本思想</strong>:准备五个img标签,为了方便控制都放在一个div里面,设置div的定位方式为 fixed,设置成这中定位方式主要是为了解决在页面出现滚动条的情况下,图片还能够跟随鼠标移动。然后再鼠标移动的时候,延时给每一个图片设置定位的left和top距离就OK了。HTML和CSS代码如下:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="font-size: 15px;"><span style="color: #008080;"> 1</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">html </span><span style="color: #ff0000;">xmlns</span><span style="color: #0000ff;">="http://www.w3.org/1999/xhtml"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;"> 2</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">style </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text/css"</span><span style="color: #ff0000;"> rel</span><span style="color: #0000ff;">="stylesheet"</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;"> 4</span> <span style="background-color: #f5f5f5; color: #800000;"> div</span><span style="background-color: #f5f5f5; color: #000000;">{</span><br/><span style="color: #008080;"> 5</span> <span style="background-color: #f5f5f5; color: #ff0000;"> width</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;">100px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;"> 6</span> <span style="background-color: #f5f5f5; color: #ff0000;"> height</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;">80px</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;"> 7</span> <br/><span style="color: #008080;"> 8</span> <span style="background-color: #f5f5f5; color: #ff0000;"> position</span><span style="background-color: #f5f5f5; color: #000000;">:</span><span style="background-color: #f5f5f5; color: #0000ff;">fixed</span><span style="background-color: #f5f5f5; color: #000000;">;</span><br/><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">style</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">10</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">11</span> <br/><span style="color: #008080;">12</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span> <br/><span style="color: #008080;">13</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div </span><span style="color: #0000ff;">&gt;&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="images/tianshi.gif"</span><span style="color: #ff0000;"> alt</span><span style="color: #0000ff;">="天使"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">14</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="images/tianshi.gif"</span><span style="color: #ff0000;"> alt</span><span style="color: #0000ff;">="天使"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">15</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="images/tianshi.gif"</span><span style="color: #ff0000;"> alt</span><span style="color: #0000ff;">="天使"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">16</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="images/tianshi.gif"</span><span style="color: #ff0000;"> alt</span><span style="color: #0000ff;">="天使"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">17</span> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;&lt;</span><span style="color: #800000;">img </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="images/tianshi.gif"</span><span style="color: #ff0000;"> alt</span><span style="color: #0000ff;">="天使"</span> <span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">18</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #008080;">19</span> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span></span></div><p><span style="font-size: 15px;">&nbsp;</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;在JS中,给当前文档对象注册一个事件,之所以注册给document而不是body是因为,当页面中没有内容的时候,body基本上是没有大小而言。代码如下:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('8164f316-02da-4f0f-b75b-fbaa165726c2')"><span style="font-size: 15px;"></span><div id="cnblogs_code_open_8164f316-02da-4f0f-b75b-fbaa165726c2" class="cnblogs_code_hide"><span style="font-size: 15px;"><span style="color: #008080;"> 1</span> &lt;script type="text/javascript" &gt;<br/><span style="color: #008080;"> 2</span> window.onload = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 3</span> document.onmousemove = <span style="color: #0000ff;">function</span><span style="color: #000000;">(evt){<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">var</span> e = evt ||<span style="color: #000000;"> window.event;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #008000;">//</span><span style="color: #008000;">拿到鼠标当前的坐标</span><br/><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">var</span> x = parseInt(e.clientX) + 5<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">var</span> y = parseInt(e.clientY) + 5<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 8</span> <span style="color: #008000;">//</span><span style="color: #008000;">获取页面上的div控件</span><br/><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">var</span> imgs = document.getElementsByTagName('div'<span style="color: #000000;">);<br/></span><span style="color: #008080;">10</span> <br/><span style="color: #008080;">11</span> setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">12</span> imgs[0].style.left = x + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">13</span> imgs[0].style.top = y + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">14</span> },0<span style="color: #000000;">);<br/></span><span style="color: #008080;">15</span> setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">16</span> <span style="color: #008000;">//</span><span style="color: #008000;"> var j = i;</span><br/><span style="color: #008080;">17</span> imgs[1].style.left = x + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">18</span> imgs[1].style.top = y + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">19</span> },50<span style="color: #000000;">);<br/></span><span style="color: #008080;">20</span> setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">21</span> imgs[2].style.left = x + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">22</span> imgs[2].style.top = y + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">23</span> },100<span style="color: #000000;">);<br/></span><span style="color: #008080;">24</span> setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">25</span> imgs[3].style.left = x + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">26</span> imgs[3].style.top = y + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">27</span> },150<span style="color: #000000;">);<br/></span><span style="color: #008080;">28</span> setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">29</span> imgs[4].style.left = x + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">30</span> imgs[4].style.top = y + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">31</span> },200<span style="color: #000000;">);<br/></span><span style="color: #008080;">32</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">33</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">34</span> &lt;/script&gt;</span></div><span class="cnblogs_code_collapse" style="font-size: 15px;">简单繁琐代码段</span></div><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;通过上面的代码基本上就已经实现了我们想要的效果,但是非常的繁琐,如果想再添加几个图片,又需要重新的拷贝一大片,还需要计算时间等,不过比较容易理解。</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;从上面的代码中可以看出,其实每一个setTimeout中代码都是一样的,不同的是imags的索引而已,而且 在每一个setTimeout中传递的都是一个匿名函数。故可以通过一个循环来进行控制,在代码中setTimeout里面传递的是一个匿名函数,是需要引用外部变量的。但由于循环变量i在循环执行完成后已经是5,而在引用它的匿名函数中并不会被驻留,于是最后通过给一个自我执行的匿名函数传参的方式,来使每一个匿名函数来给里面的匿名函数(闭包)维护一个变量作用域。改良后的代码如下:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="font-size: 15px;"><span style="color: #008080;"> 1</span> &lt;script type="text/javascript" &gt;<br/><span style="color: #008080;"> 2</span> window.onload = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;"> 3</span> document.onmousemove = <span style="color: #0000ff;">function</span><span style="color: #000000;">(evt){<br/></span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">var</span> e = evt ||<span style="color: #000000;"> window.event;<br/></span><span style="color: #008080;"> 5</span> <span style="color: #008000;">//</span><span style="color: #008000;">拿到鼠标当前的坐标</span><br/><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">var</span> x = parseInt(e.clientX) + 5<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">var</span> y = parseInt(e.clientY) + 5<span style="color: #000000;">;<br/></span><span style="color: #008080;"> 8</span> <span style="color: #008000;">//</span><span style="color: #008000;">获取页面上的div控件</span><br/><span style="color: #008080;"> 9</span> <span style="color: #0000ff;">var</span> imgs = document.getElementsByTagName('div'<span style="color: #000000;">);<br/></span><span style="color: #008080;">10</span> <br/><span style="color: #008080;">11</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">var</span> i=0;i&lt;imgs.length;i++<span style="color: #000000;">){<br/></span><span style="color: #008080;">12</span> <span style="color: #008000;">//</span><span style="color: #008000;">通过参数的形式把i传递过来,就能够将每一个i的值一直保存在内存中,直到闭包的匿名函数不在使用它</span><br/><span style="color: #008080;">13</span> (<span style="color: #0000ff;">function</span><span style="color: #000000;">(j){<br/></span><span style="color: #008080;">14</span> setTimeout(<span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br/></span><span style="color: #008080;">15</span> imgs[j].style.left = x + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">16</span> imgs[j].style.top = y + 'px'<span style="color: #000000;">;<br/></span><span style="color: #008080;">17</span> },j*40<span style="color: #000000;">)<br/></span><span style="color: #008080;">18</span> <span style="color: #000000;"> })(i);<br/></span><span style="color: #008080;">19</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">20</span> <span style="color: #000000;"> };<br/></span><span style="color: #008080;">21</span> <span style="color: #000000;"> }<br/></span><span style="color: #008080;">22</span> &lt;/script&gt;</span></div><p><span style="font-size: 15px;">&nbsp;</span></p><p><span style="font-size: 15px;">&nbsp;</span></p><img src="http://counter.cnblogs.com/blog/rss/3866810" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/qigang/p/3866810.html" target="_blank">JS中图片飞飞效果</a>,转载请注明。</p>

高级...
微信扫一扫
关注无线梦工厂
返回主页 手机网推广 加入Timewe 反馈意见 关于我们 加入收藏 点击这里给我发消息加关注加微信好友

触屏版,3G,Wap,手机网站,浏览器,pc版,在线,嵌入式,Wap浏览器,电脑上的Wap浏览器 各主流搜索引擎收录Timewe
(R)2009-2019 Timewe 时维网络科技有限公司 (86)0755-36601136
简体/繁体