Node.js和Filesystem:这是竞争条件吗?

前端之家收集整理的这篇文章主要介绍了Node.js和Filesystem:这是竞争条件吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在类中有以下代码. (这是coffeescript–它是一个couchdb实用程序! – 但这确实是一个node.js问题).我正在尝试使用Node 0.49做Node Node,这意味着使用异步调用来进行文件系统操作.起初,我正在把头发拉出来,因为这个过程在处理过程中几次变为零,所以我知道我在那里做错了.但后来我遇到了一个更棘手的问题:在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,files) =>
        for fname in files
            console.log("X1: ",fname)
            fs.stat path.join(dirpath,fname),stats) =>
                console.log("X2: ",fname)
                if stats.isFile()
                    @load_file(dirpath,fname,object)
                if stats.isDirectory()
                    object[fname] = {}
                    @load_directory(path.join(dirpath,object[fname])
        @check_sentinel()

这是我得到的:

X1:  memberByName.js
X1:  memberByClub.js
X2:  memberByClub.js
X2:  memberByClub.js

这是超现实的,它看起来很像竞争条件. “memberByName”被传递给fs.stat(),后者又将“memberByClub”传递给load_file(),暗示……什么?那是因为load_file()立即返回,它绕过并将数组中的下一个文件名提供给函数调用?或者我对给定范围内的值的持久性有一些误解?

解决方法

不,你看到的是预期的.你必须记住的一件事是fs.stat是异步的.因此,外部循环(对于文件中的fname)将在调用fs.stat的任何回调之前完成循环.

你看到memberByClub.js两次的原因是你在logging语句中使用fname,但是该变量来自闭包,它在你调用fs.stat的回调时已经改变了.

你可以使用do(fname)=>包装内部循环.获取正确的日志记录语句,但我认为您需要重新构建代码以实现您尝试对整个类进行的操作.

load_directory: (dirpath,files) =>
        for fname in files
            do (fname) =>
                console.log("X1: ",fname)
                fs.stat path.join(dirpath,stats) =>
                    console.log("X2: ",fname)
                    if stats.isFile()
                         @load_file(dirpath,object)
                    if stats.isDirectory()
                        object[fname] = {}
                        @load_directory(path.join(dirpath,object[fname])
        @check_sentinel()

猜你在找的Node.js相关文章