我正在练习node.js,我有一些疑问。
我有一个csv文件(users.csv),我创建了一个节点模块(library.js)来返回csv文件中的值。当我从我的程序中调用模块时,我得到了结果。我的计划如下。
users.csv
id,name
1,Jim
2,Jo
library.js
var csv = require("fast-csv");
var DataToBeReturned = [];
exports.users = function () {
csv.fromPath("users.csv", {headers: true})
.on("data",function(data){
DataToBeReturned.push(data);
})
.on("end",function(){
console.log(DataToBeReturned.length);
return DataToBeReturned;
});
};
app.js
var mylibrary = require('./library.js');
console.log(mylibrary.users());
console.log(mylibrary.users());
我的预期输出是
2
[{ id: '1', name: 'Jim' },{ id: '2', name: 'Jo' }]
2
[{ id: '1', name: 'Jim' },{ id: '2', name: 'Jo' }]
相反,我得到了
undefined
undefined
3
4
我的怀疑:
提前致谢。
答案 0 :(得分:1)
我自己无法测试您的代码,但是通过阅读您的代码,您遇到了两个问题,这些问题与您的问题密切相关。
首先,您遇到了大多数人在使用nodejs时遇到的典型问题。您正在同步调用异步函数。这就是为什么它的前两次打印未定义,你打印调用用户的结果。由于用户还没有完成运行,它的值是未定义的。您应该使用回调实现library.js
函数用户。例如:
exports.users = function (callback) {
csv.fromPath("users.csv", {headers: true})
.on("data",function(data){
DataToBeReturned.push(data);
})
.on("end",function(){
console.log(DataToBeReturned.length);
return callback(null, DataToBeReturned);
});
};
然后在app.js
中,您将实现此操作以使用回调。
var csv = require("fast-csv");
// err is just a nodejs convention, if you add error checking to users,
// instead of throwing an error, you would pass it back as the first agrument
// to the callback
mylibrary.users(function(err, users) {
console.log(users);
});
mylibrary.users(function(err, users) {
console.log(users);
});
其次,您指的是users
函数中的全局变量。那就是你打印出3和4.两个调用都立即对变量进行操作。当第一个调用完成并返回值时,第二个调用也已经修改了数组。因此,您希望移动数组声明而不是函数,因此只有那里的代码才能访问它。
exports.users = function () {
var DataToBeReturned = [];
// the rest of your code.
};
编辑:模块内的代码被缓存,因此只执行一次。然后,引用它的每个脚本都只返回该副本。如果您只需要阅读一次csv,请使用此功能。
var DataToBeReturned = [];
var called = false;
function read(callback) {
if (called) {
process.nextTick(function() {
return callback(null, DataToBeReturned);
});
return;
} else {
called = true;
csv.fromPath("users.csv", {headers: true})
.on("data",function(data){
DataToBeReturned.push(data);
})
.on("end",function(){
console.log(DataToBeReturned.length);
return callback(null, DataToBeReturned);
});
}
};
exports.users = function(callback) {
return read(callback);
};
process.nextTick部分很重要,有关其工作原理的更多信息可以在文档中找到here。