2017-04-26 22 views
-1

我在我的nodejs中使用express來獲得以下函數。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

什麼呢myArr,該返回,如果你註銷它? – jsw324

+0

你需要使用一個同步readFile函數(谷歌),否則該回調函數中的代碼單獨發生。 –

回答

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

並且你使用這樣的:

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模塊(https://nodejs.org/api/fs.html#fs_fs_readfilesync_file_options

或者的readFileSync方法異步/ AWAIT,但要小心兼容性(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

+0

謝謝,我如何包含兩個'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

使用fs.readFileSync

Here is a good example

希望它能幫助,

最好的問候,

1

fs.readFile是一個異步調用。

你可以使用函數作爲回調並調用它的廣告你的異步調用的結束,也可以在一個承諾

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

這是一個asynchrone問題與您的代碼包裝你的電話。

您應該使用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; 
});