将作用域传递给自执行函数内部的函数
Passing scope to function inside self-exec function
这可能看起来像是一个初学者的问题,但我已经自学了所有关于 JS 的知识(感谢 Stack Overflow!)。
这是一个以复杂的方式传递范围的问题。我有一种感觉,必须使用 apply 或 bind 来解决,我很难理解。
我有一个解析器 class 来处理我拥有的许多类似 CSV 的大型文件。这些文件都包含不同的信息,需要以不同的方式处理。为了演示,我们称它们为 foo.csv 和 bar.csv。该示例过于简单,但它说明了我遇到的问题。
构造函数:
function Parser() {
this.csvFoo = './foo.csv';
this.csvBar = './bar.csv';
this.parsedInfo = {
foos: [],
bars: []
};
}
然后我有两个函数来处理这两种类型的文件:
Parser.prototype._parseFoo = function(line, cb) {
var fields = this._parseLine(line,',');
this.parsedInfo.foos.push({
foo1: fields[1],
foo2: fields[2]
});
cb();
};
Parser.prototype._parseBar = function(line, cb) {
var fields = this._parseLine(line,',');
this.parsedInfo.bars.push({
bar1: fields[1],
bar2: fields[2]
});
cb();
};
以及根据分隔符分割一行的函数:
Parser.prototype._parseLine = function(line, delim) {
return (line.split(delim));
};
流式传输文件并进行解析的函数如下:
Parser.prototype._streamParseFile = function(file, makeObj, cb) {
var self = this;
var lineNum = 0;
var s = fs.createReadStream(file).pipe(es.split()).pipe(es.mapSync(function(line) {
s.pause();
(function() {
makeObj(line, function(sale) {
s.resume();
});
})();
}).on('error', function(err) {
console.log('Error');
console.log(err);
}).on('end', function() {
console.log('done');
cb();
}));
};
我这样称呼它:
Parser.prototype.insertFoos = function() {
var self = this;
self._streamParseFile(self.csvFoo,self._parseFoo,function() {
console.log('Done Foo');
});
};
我遇到的问题是,当它到达 _parseFoo 时,"this" 对象没有正确设置,所以在那种情况下我不能使用 this._parseLine()。
我以为我可以使用 :
makeObj(line, function(sale) {
s.resume();
}).bind(self);
但它不起作用。我目前正在阅读文档和文章,但我知道这是一个我不精通的领域,所以解释一下会有很大帮助。
你会想做的
Parser.prototype.insertFoos = function() {
this._streamParseFile(this.csvFoo, this._parseFoo.bind(this), function() {
// ^^^^^^^^^^^
console.log('Done Foo');
});
};
请注意,您的 es.mapSync
回调过于复杂(没有理由使用 IEFE!)并且您(还?)实际上不需要 makeObj
- parseFoo
的回调是同步的。
这可能看起来像是一个初学者的问题,但我已经自学了所有关于 JS 的知识(感谢 Stack Overflow!)。
这是一个以复杂的方式传递范围的问题。我有一种感觉,必须使用 apply 或 bind 来解决,我很难理解。
我有一个解析器 class 来处理我拥有的许多类似 CSV 的大型文件。这些文件都包含不同的信息,需要以不同的方式处理。为了演示,我们称它们为 foo.csv 和 bar.csv。该示例过于简单,但它说明了我遇到的问题。
构造函数:
function Parser() {
this.csvFoo = './foo.csv';
this.csvBar = './bar.csv';
this.parsedInfo = {
foos: [],
bars: []
};
}
然后我有两个函数来处理这两种类型的文件:
Parser.prototype._parseFoo = function(line, cb) {
var fields = this._parseLine(line,',');
this.parsedInfo.foos.push({
foo1: fields[1],
foo2: fields[2]
});
cb();
};
Parser.prototype._parseBar = function(line, cb) {
var fields = this._parseLine(line,',');
this.parsedInfo.bars.push({
bar1: fields[1],
bar2: fields[2]
});
cb();
};
以及根据分隔符分割一行的函数:
Parser.prototype._parseLine = function(line, delim) {
return (line.split(delim));
};
流式传输文件并进行解析的函数如下:
Parser.prototype._streamParseFile = function(file, makeObj, cb) {
var self = this;
var lineNum = 0;
var s = fs.createReadStream(file).pipe(es.split()).pipe(es.mapSync(function(line) {
s.pause();
(function() {
makeObj(line, function(sale) {
s.resume();
});
})();
}).on('error', function(err) {
console.log('Error');
console.log(err);
}).on('end', function() {
console.log('done');
cb();
}));
};
我这样称呼它:
Parser.prototype.insertFoos = function() {
var self = this;
self._streamParseFile(self.csvFoo,self._parseFoo,function() {
console.log('Done Foo');
});
};
我遇到的问题是,当它到达 _parseFoo 时,"this" 对象没有正确设置,所以在那种情况下我不能使用 this._parseLine()。
我以为我可以使用 :
makeObj(line, function(sale) {
s.resume();
}).bind(self);
但它不起作用。我目前正在阅读文档和文章,但我知道这是一个我不精通的领域,所以解释一下会有很大帮助。
你会想做的
Parser.prototype.insertFoos = function() {
this._streamParseFile(this.csvFoo, this._parseFoo.bind(this), function() {
// ^^^^^^^^^^^
console.log('Done Foo');
});
};
请注意,您的 es.mapSync
回调过于复杂(没有理由使用 IEFE!)并且您(还?)实际上不需要 makeObj
- parseFoo
的回调是同步的。