te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Add additional parameters to callback function - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Add additional parameters to callback function - Stack Overflow

programmeradmin3浏览0评论

I'm building a system in Node.js that is supposed to find all files in an array of folders, stat them, and then do some additional work using that information.

I'm using fs.readdir() to get all the files synchronously from each of the folders. My code looks like this:

for(i=0,max=paths.length; i<max; i++) {
    var path = paths.pop();
    console.log("READING PATH: " + path);
    fs.readdir(path, function(err, files) { handleDir(err, files, path); });
}

The problem is that, depending on how fast the readdir() executes, handleDir() is getting the wrong path. This happens because by the time the callback runs, the next loop has already started - meaning that the path variable has changed.

So, what I need to do is somehow lock that path variable to it's specific callback function. I can't think of any good way to do this - anyone have some ideas?

I'm building a system in Node.js that is supposed to find all files in an array of folders, stat them, and then do some additional work using that information.

I'm using fs.readdir() to get all the files synchronously from each of the folders. My code looks like this:

for(i=0,max=paths.length; i<max; i++) {
    var path = paths.pop();
    console.log("READING PATH: " + path);
    fs.readdir(path, function(err, files) { handleDir(err, files, path); });
}

The problem is that, depending on how fast the readdir() executes, handleDir() is getting the wrong path. This happens because by the time the callback runs, the next loop has already started - meaning that the path variable has changed.

So, what I need to do is somehow lock that path variable to it's specific callback function. I can't think of any good way to do this - anyone have some ideas?

Share Improve this question asked May 13, 2011 at 20:17 jwegnerjwegner 7,4238 gold badges37 silver badges58 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 7

There is no block scope, so use a function for scope.

for(var i=0, path, max=paths.length; i<max; i++) {
    path = paths.pop();
    console.log("READING PATH: " + path);
    handlePath( path );
}
function handlePath ( path ) {
    fs.readdir(path, onPathRead);
    function onPathRead (err, files) {
        handleDir(err, files, path);
    }
}

This is one of the more annoying parts of JS for me. An alternative to creating a separate function (as @generalhenry demonstrated) is to wrap the code in an anonymous function that's executed before the path variable changes.

for(i=0,max=paths.length; i<max; i++) {
    var path = paths.pop();
    console.log("READING PATH: " + path);
    fs.readdir(path,
        (function(p){
            return function(err, files) {
                handleDir(err, files, p);
            };
        })(path);
    );
}

Either way, the important point is that the function's context (anonymous or not) is initiated before the value of the path variable is reassigned.

This is indeed an annoying feature of Javascript, so much so that Coffeescript (which is a language that piles down to Javascript) has a specific way of dealing with it, the do operator on for. In Coffeescript your original function would be:

for path in paths
     fs.readdir path, (err, files) -> handleDir(err, files, path)

and the solution to your problem would be:

for path in paths
   do (path) ->
     fs.readdir path, (err, files) -> handleDir(err, files, path)

I was looking for the same thing and end up with the solution and here it's a simple example if anybody wants to go through this.

var FA = function(data){
   console.log("IN A:"+data)
   FC(data,"LastName");
};
var FC = function(data,d2){
   console.log("IN C:"+data,d2)
};
var FB = function(data){
   console.log("IN B:"+data);
    FA(data)
};
FB('FirstName')

Great solution from generalhenry, but be careful if you're going to use a try/catch structure inside the callback function

function handlePath ( path ) {
    fs.readdir(path, onPathRead);
    function onPathRead (err, files) {
        try {
            handleDir(err, files, path);
        } catch (error) {
            var path = 'something_else'; // <<--- Never do this !!!
        }     
    }
}

Never try to redeclare the same var in a catch block, even if the catch block is never invoked, the path var is reset and you will find it as 'undefined' when the callback is executed. Try this simple example:

function wrapper(id) {
    console.log('wrapper id:' + id);
    setTimeout(callback, 1000);
    function callback() {
        try {
            console.log('callback id:' + id);
        } catch (error) {
            var id = 'something_else';
            console.log('err:' + error);
        }
    }
}

wrapper(42);

This will output:

wrapper id:42
callback id:undefined
发布评论

评论列表(0)

  1. 暂无评论