2017-04-26 9 views
-1

expressを使用してnodejsに以下の関数を持っています。nodejs express関数がfs.readFileから変数を返さない

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の更新された値を返すにはどうすればよいですか?

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)(https://nodejs.org/api/fs.html#fs_fs_readfilesync_file_options

またはasync /のawait FSモジュールのreadFileSyncメソッドを使用しますが、互換性に注意することができあなたはそれをログアウトしますか? – jsw324

+0

あなたは同期readFile関数(Google)を使用する必要があります。そうでなければ、そのコールバック関数内のコードは別々に発生します。 –

答えて

1

fs.readFileが非同期であるとして、あなたはコールバックまたは、例えば約束を使用する必要があります。

コールバック:

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) 
    }); 
}; 

そして、あなたはこのようにそれを使用する:あなたはこのようにそれを使用します

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; }; 
約束

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

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promiseを参照)

また場合myArrリターンを何

+0

ありがとう、私は2つの 'fs.readFile'をインクルードし、関数の結果としてcount1とcount2を渡すことができますか? – passion

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

使用を

Here is a good example

はそれが役に立てば幸いfs.readFileSync

敬具、

1

fs.readFileは非同期呼び出しです。

あなたはコールバックとしての機能を使用して、それを呼び出す広告あなたの非同期呼び出しの終わりか、それはあなたのコードでasynchroneの問題である約束

var Promise = require('bluebird'); 

var MyReadFileAsync = function (filename) { 
    return new Promise(function (resolve, reject) { 

     fs.readFile(filename, 'utf8', function (err, 
     data) { 

     if (err) reject(err); 
     obj = JSON.parse(data); 
     var myArr = obj.nodes; 
     resolve(Object.keys(myArr).length); 
    }); 

    }); 
}; 

MyReadFileAsync(__dirname +'/' + dir+'/myfile.json').then(function(counter){ 
var myCounterUpdated = counter; 
}) 
1

であなたの呼び出しをラップすることができます。

NodeJSには "async"ライブラリを使用する必要があります。 exempleについては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; 
}); 
関連する問題