Page 142 - Node.js开发指南
P. 142

6.2  控制流    135


                       如果加载失败,令current_dir为其父目录。                                                     1
                       重复这一过程,直到遇到根目录,抛出异常,结束。

               6.2  控制流
                                                                                                      2
                   基于异步 I/O  的事件式编程容易将程序的逻辑拆得七零八落,给控制流的疏理制造障
               碍。让我们通过下面的例子来说明这个问题。

               6.2.1  循环的陷阱                                                                           3

                   Node.js  的异步机制由事件和回调函数实现,一开始接触可能会感觉违反常规,但习惯
               以后就会发现还是很简单的。然而这之中其实暗藏了不少陷阱,一个很容易遇到的问题就是
               循环中的回调函数,初学者经常容易陷入这个圈套。让我们从一个例子开始说明这个问题。                                               4


                   //forloop.js

                   var fs = require('fs');
                   var files = ['a.txt', 'b.txt', 'c.txt'];                                           5

                   for (var i = 0; i < files.length; i++) {
                     fs.readFile(files[i], 'utf-8', function(err, contents) {
                       console.log(files[i] + ': ' + contents);
                     });
                   }                                                                                  6
                   这段代码的功能很直观,就是依次读取文件 a.txt、b.txt、c.txt,并输出文件名和内容。
               假设这三个文件的内容分别是 AAA、BBB 和 CCC,那么我们期望的输出结果就是:
                                                                                                      7
                   a.txt: AAA
                   b.txt: BBB
                   c.txt: CCC
               可是我们运行这段代码的结果是怎样的呢?竟然是这样的结果:
                                                                                                      8
                   undefined: AAA
                   undefined: BBB
                   undefined: CCC
                   这个结果说明文件内容正确输出了,而文件名却不对,也就意味着,contents 的结果                                         9
               是正确的,但 files[i] 的值是 undefined。这怎么可能呢,文件名不正确却能读取文件
               内容?既然难以直观地理解,我们就把 files[i] 分解并打印出来看看,在读取文件的回调
               函数中分别输出 files、i 和 files[i]。
                                                                                                      10
   137   138   139   140   141   142   143   144   145   146   147