我在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
的更新值?
答案 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
希望它有所帮助,
致以最诚挚的问候,
答案 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)