nodejs表示函数不从fs.readFile返回变量

时间:2017-04-26 13:16:27

标签: javascript json node.js express

我在nodejs中使用express。

function metaInfo (id){

    var dir = 'files/'+id;
    var count = 0

    fs.readFile(__dirname +'/' + dir+'/myfile.json', 'utf8', function (err, data) {

        if (err) throw err;
        obj = JSON.parse(data);
        var myArr = obj.nodes;
        var count = Object.keys(myArr).length;
        console.log("counting :", count)
    });

    return count
};

当我调用此函数时,count为零,但是,它是fs.readFile内的正确值。如何返回count的更新值?

4 个答案:

答案 0 :(得分:1)

fs.readFile是一个异步函数,所以当你的函数返回count时,文件还没有打开。

以下是您可以做的事情:

function metaInfo (id, callback){

    var dir = 'files/'+id;
    var count = 0

    fs.readFile(__dirname +'/' + dir+'/myfile.json', 'utf8', function (err, data) {

        if (err) throw err;
        obj = JSON.parse(data);
        var myArr = obj.nodes;
        count = Object.keys(myArr).length;
        callback(count);
    });
};

metaInfo("yourId", function(count) {
  // Here is your count
});

OR

使用fs.readFileSync

Here is a good example

希望它有所帮助,

致以最诚挚的问候,

答案 1 :(得分:1)

fs.readFile是异步调用。

你可以使用一个函数作为回调,并在你的异步调用结束时调用它,或者你可以将你的调用包装在一个承诺中

unameit@Unameit:~/node/example2$ sudo npm install hubot-nagios4 --save

> contextify@0.1.15 install /home/unameit/node/example2/node_modules/contextify
> node-gyp rebuild

gyp WARN EACCES user "root" does not have permission to access the dev dir "/home/unameit/.node-gyp/6.9.1"
gyp WARN EACCES attempting to reinstall using temporary dev dir "/home/unameit/node/example2/node_modules/contextify/.node-gyp"
gyp WARN install got an error, rolling back install
gyp WARN install got an error, rolling back install
gyp ERR! configure error 
gyp ERR! stack Error: unable to get local issuer certificate
gyp ERR! stack     at Error (native)
gyp ERR! stack     at TLSSocket.<anonymous> (_tls_wrap.js:1062:38)
gyp ERR! stack     at emitNone (events.js:86:13)
gyp ERR! stack     at TLSSocket.emit (events.js:185:7)
gyp ERR! stack     at TLSSocket._finishInit (_tls_wrap.js:586:8)
gyp ERR! stack     at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:416:38)
gyp ERR! System Linux 3.13.0-74-generic
gyp ERR! command "/mnt/node/node-v6.9.1-linux-x86/bin/node" "/mnt/node/node-v6.9.1-linux-x86/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/unameit/node/example2/node_modules/contextify
gyp ERR! node -v v6.9.1
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok 
npm WARN example2@0.0.0 No repository field.
npm ERR! Linux 3.13.0-74-generic
npm ERR! argv "/mnt/node/node-v6.9.1-linux-x86/bin/node" "/usr/local/bin/npm" "install" "hubot-nagios4" "--save"
npm ERR! node v6.9.1
npm ERR! npm  v3.10.8
npm ERR! code ELIFECYCLE

npm ERR! contextify@0.1.15 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the contextify@0.1.15 install script 'node-gyp rebuild'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the contextify package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs contextify
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls contextify
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /home/unameit/node/example2/npm-debug.log

答案 2 :(得分:1)

这是您的代码的异步问题。

你可以使用&#34; async&#34; NodeJS的库。 Async documentation

例如,你可以包装你的:

fs.readFile(__dirname +'/' + dir+'/myfile.json', 'utf8', function (err, data) {

    if (err) throw err;
    obj = JSON.parse(data);
    var myArr = obj.nodes;
    var count = Object.keys(myArr).length;
    console.log("counting :", count)
});

致:

async.waterfall([
    function(callback) {
        fs.readFile(__dirname +'/' + dir+'/myfile.json', 'utf8', function (err, data) {

            if (err) throw err;
            obj = JSON.parse(data);
            var myArr = obj.nodes;
            var count = Object.keys(myArr).length;
            console.log("counting :", count);
            callback(null, count);
        });

    }
], function (err, result) {
    // result now equals  = count
    return result;
});

答案 3 :(得分:1)

由于fs.readFile是异步的,因此您需要使用回调或Promise。

回调:

function metaInfo (id, cb){

    var dir = 'files/'+id;
    var count = 0

    fs.readFile(__dirname +'/' + dir+'/myfile.json', 'utf8', function (err, data) {
        if (err) cb(err);
        obj = JSON.parse(data);
        var myArr = obj.nodes;
        var count = Object.keys(myArr).length;
        console.log("counting :", count)
        cb(null, count)
    });
};

你这样使用它:

metaInfo(1, function(err, result) {
  if(err) throw err;
  console.log('Count:', result);
});

承诺:

function metaInfo (id){
    return new Promise(function(resolve, reject) {
        var dir = 'files/'+id;
        var count = 0

        fs.readFile(__dirname +'/' + dir+'/myfile.json', 'utf8', function (err, data) {
            if (err) reject(err);
            obj = JSON.parse(data);
            var myArr = obj.nodes;
            var count = Object.keys(myArr).length;
            console.log("counting :", count);
            resolve(count);
        });
    });
};

你会像这样使用它:

metaInfo(1)
    .then(function(count) { console.log('Count:', count); 
    .catch(function(error) { throw error; };

(见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

你也可以使用fs模块的readFileSync方法(https://nodejs.org/api/fs.html#fs_fs_readfilesync_file_options

或async / await,但要注意兼容性(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function