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