首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Node.js和文件系统:这是一个竞争条件吗?

Node.js和文件系统:这是一个竞争条件吗?
EN

Stack Overflow用户
提问于 2011-07-10 17:03:59
回答 1查看 861关注 0票数 6

我在一个类中有以下代码。(这是coffeescript--用于couchdb实用程序!--但这确实是一个node.js问题)。我试图使用Node 0.49来完成Node方式,这意味着对文件系统操作使用异步调用。一开始,我把头发拔了出来,因为在处理过程中,this.sentinel几次降到零,所以我知道我做错了什么。但后来我遇到了一个更奇怪的问题:在load_directory中,看到那些console.log()调用了吗?当我运行这个的时候要注意。

代码语言:javascript
复制
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()

我得到的是:

代码语言:javascript
复制
X1:  memberByName.js
X1:  memberByClub.js
X2:  memberByClub.js
X2:  memberByClub.js

这是超现实的,它看起来很像一个种族的条件。"memberByName“被传递给fs.stat(),而fs.stat()又将"memberByClub”传递给load_file(),这意味着.什么?因为load_file()立即返回,所以它到处跑,并将数组中的下一个文件名呈现给函数调用?还是我对给定范围内的价值持续存在有一些误解?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-07-10 17:20:54

不,你看到的都是意料之中的。您必须记住的一点是,fs.stat是异步的。因此,外部循环(for fname in files)将在调用对fs.stat的任何回调之前完成循环。

您之所以两次看到memberByClub.js,是因为您在日志语句中使用了fname,但是该变量来自闭包,在调用回fs.stat时,闭包已经发生了更改。

您可以使用do (fname) =>包装内部循环,以获得正确的日志语句,但我认为您需要重新构造代码,以实现对整个类所做的工作。

代码语言:javascript
复制
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()
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6642513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档