我在一个类中有以下代码。(这是coffeescript--用于couchdb实用程序!--但这确实是一个node.js问题)。我试图使用Node 0.49来完成Node方式,这意味着对文件系统操作使用异步调用。一开始,我把头发拔了出来,因为在处理过程中,this.sentinel几次降到零,所以我知道我做错了什么。但后来我遇到了一个更奇怪的问题:在load_directory中,看到那些console.log()调用了吗?当我运行这个的时候要注意。
check_sentinel: ->
@sentinel--
if @sentinel == 0
@emit('designDirLoaded', @object)
load_file: (rootdir, filename, object) ->
@sentinel++
fname = path.join(rootdir, filename)
@manifest.push(fname)
fs.readFile fname, (err, data) =>
object[filename] = data
@check_sentinel()
load_directory: (dirpath, object) ->
@sentinel++
fs.readdir dirpath, (err, files) =>
for fname in files
console.log("X1: ", fname)
fs.stat path.join(dirpath, fname), (err, stats) =>
console.log("X2: ", fname)
if stats.isFile()
@load_file(dirpath, fname, object)
if stats.isDirectory()
object[fname] = {}
@load_directory(path.join(dirpath, fname), object[fname])
@check_sentinel()我得到的是:
X1: memberByName.js
X1: memberByClub.js
X2: memberByClub.js
X2: memberByClub.js这是超现实的,它看起来很像一个种族的条件。"memberByName“被传递给fs.stat(),而fs.stat()又将"memberByClub”传递给load_file(),这意味着.什么?因为load_file()立即返回,所以它到处跑,并将数组中的下一个文件名呈现给函数调用?还是我对给定范围内的价值持续存在有一些误解?
发布于 2011-07-10 17:20:54
不,你看到的都是意料之中的。您必须记住的一点是,fs.stat是异步的。因此,外部循环(for fname in files)将在调用对fs.stat的任何回调之前完成循环。
您之所以两次看到memberByClub.js,是因为您在日志语句中使用了fname,但是该变量来自闭包,在调用回fs.stat时,闭包已经发生了更改。
您可以使用do (fname) =>包装内部循环,以获得正确的日志语句,但我认为您需要重新构造代码,以实现对整个类所做的工作。
load_directory: (dirpath, object) ->
@sentinel++
fs.readdir dirpath, (err, files) =>
for fname in files
do (fname) =>
console.log("X1: ", fname)
fs.stat path.join(dirpath, fname), (err, stats) =>
console.log("X2: ", fname)
if stats.isFile()
@load_file(dirpath, fname, object)
if stats.isDirectory()
object[fname] = {}
@load_directory(path.join(dirpath, fname), object[fname])
@check_sentinel()https://stackoverflow.com/questions/6642513
复制相似问题