在Test里面有两个方法,getInfo 与pushSeller,当我在pushSeller中调用getInfo时是为定义错误。请问是作用域得问题吗?谢谢!
function Test() {
this.style = new Xinge.Style(4, 1, 1, 1, 0);
this.getInfo = function (os, flag) {
this.accessId = Number(process.env['XINGE_' + flag +'_' + os + '_ACCESS_ID']);
this.secretKey = process.env['XINGE_' + flag + '_' + os + '_SECRET_KEY'];
this.XingeApp = new Xinge.XingeApp(this.accessId, this.secretKey);
}
this.pushSeller = function (seller_id, title, content) {
console.log(this.getInfo); //在这我可用访问到getInfo
db.query(
"SELECT * FROM seller_admin WHERE seller_id=?", [seller_id],
function (err, seller_admin) {
if (err) {
return console.log(err);
}
if (seller_admin.length) {
for (var i = 0; i < seller_admin.length; i++) {
(function (i) {
db.query(
"SELECT os, pushtoken FROM user WHERE uid =?", [seller_admin[i].uid],
function (err, user) {
if (err) {
return console.log(err);
}
if (user[0].pushtoken) {
if (user[0].os == 'android') {
console.log(user);
this.getInfo('ANDROID', 'SHOP'); //在这里我访问不到getInfo
this.android(user[0].pushtoken, title, content)
}
}
}
);
})(i);
}
}
}
);
}
}
进回调了,肯定拿不到。 db.query() 明显进回调了。 //混合(MIX)方法到SESSION或者GLOBAL。是最佳解决方法。
@MiguelValentine 还是有点不理解,回调里面不能访问外部函数?要传参数?
@youqingkui 是啊,回调里面的方法拿不到外部函数。传参都没用呢。用公用变量或者全局变量解决吧。
@MiguelValentine 嗯,谢谢!
this指向当前函数.你看看你用this时,this指向谁?
@MiguelValentine 不对。怎么可能拿不到? 闭包。
@ngot 难道我这个this没有指向到当前对象?
@youqingkui 指向了。但是当前对象是谁呢?
@ngot 我console.log(this),得道德是下面得东西。this变成了db.query?
{ domain: null,
_events:
{ error: [Function],
packet: [Function],
end: [Function],
timeout: [Function],
'start-tls': [Function] },
_maxListeners: 10,
_callback: [Function],
_callSite: null,
_ended: true,
_timeout: undefined,
_idleNext: null,
_idlePrev: null,
_idleStart: null,
_idleTimeout: undefined,
_repeat: null,
sql: 'SELECT os, pushtoken FROM user WHERE uid =15',
values: [ 15 ],
typeCast: true,
nestTables: false,
_resultSet: null,
_results: [ [ [Object] ] ],
_fields: [ [ [Object], [Object] ] ],
_index: 1,
_loadError: null,
_connection:
{ domain: null,
_events: { error: [Function] },
_maxListeners: 10,
config:
{ host: 'localhost',
port: 3306,
localAddress: undefined,
socketPath: undefined,
user: 'root',
password: undefined,
database: 'mykar_product',
connectTimeout: 10000,
insecureAuth: false,
supportBigNumbers: false,
bigNumberStrings: false,
dateStrings: false,
debug: undefined,
trace: true,
stringifyObjects: false,
timezone: 'local',
flags: '',
queryFormat: undefined,
pool: undefined,
ssl: false,
multipleStatements: false,
typeCast: true,
maxPacketSize: 0,
charsetNumber: 33,
clientFlags: 193487,
protocol41: true },
_socket:
{ _connecting: false,
_handle: [Object],
_readableState: [Object],
readable: true,
domain: null,
_events: [Object],
_maxListeners: 10,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
onend: null,
destroyed: false,
bytesRead: 1344,
_bytesDispatched: 253,
_pendingData: null,
_pendingEncoding: '',
pipe: [Function],
addListener: [Function],
on: [Function],
pause: [Function],
resume: [Function],
read: [Function],
_consuming: true,
_idleTimeout: -1,
_idleNext: null,
_idlePrev: null,
_idleStart: 1407894192122 },
_protocol:
{ domain: null,
_events: [Object],
_maxListeners: 10,
readable: true,
writable: true,
_config: [Object],
_connection: [Circular],
_callback: null,
_fatalError: null,
_quitSequence: null,
_handshakeSequence: [Object],
_handshaked: true,
_ended: false,
_destroyed: false,
_queue: [Object],
_handshakeInitializationPacket: [Object],
_parser: [Object] },
_connectCalled: true,
state: 'authenticated',
threadId: 151 } }
@ngot 那请问,我如何在下面访问到Test得getInfo?谢谢!
@youqingkui 没有变啊。this永远指向当前对象啊。
@youqingkui 把getInfo做成闭包
@ngot 数据库是个坑爹异步。所以这里不存在闭包概念。用GLOBAL MIX this方法
gloabal.path = this;在上面声明,下面用global.path代替this.
@MiguelValentine 别用global,这是坑。作闭包,做保险。
@MiguelValentine 学习了,都是好方法!谢谢!
@ngot 我去掉对象Test里面得this.getInfo方法,在pushSeller里面定义一个。
function getInfo (os, flag) {
this.accessId = Number(process.env['XINGE_' + flag +'_' + os + '_ACCESS_ID']);
this.secretKey = process.env['XINGE_' + flag + '_' + os + '_SECRET_KEY'];
this.XingeApp = new Xinge.XingeApp(this.accessId, this.secretKey);
}
然后去掉下面得this.getInfo,改为getInfo(‘ANDROID’, ‘SHOP’);可以访问getInfo 了。
@youqingkui 这个方法,不错。安全。不过我的意思,不是传方法闭包。而是传外层对象的闭包,我觉得这样更优雅。
@ngot 外层对象得闭包?有点不理解,可否简单的给下代码?
@ngot 在Test里面这样定义getInfo? 然后在Test外面定义getInfo?
Test(){
this.getInfo = getInfo;
}
function getInfo(){
...
}
@youqingkui 没有很复杂,很简单的
function test1(){
var self = this;
self.getInfo = function(){
return "hello";
}
function test2(){
self.getInfo();
}
}
@ngot 反正我觉得用SESSION最保险,也不会串。
@MiguelValentine 那样session就不纯粹了
@ngot 这个好像和那位朋友的方法有些类似,gloabal.path = this; 将对象的this带到闭包里面。
@youqingkui 不要污染全局。
@ngot session反正又不是COOKIES,是为会话服务的。在服务器端的保密数据而已。既然为会话服务,传值用起来绝对好。
@MiguelValentine 拆分session的时候,你怎么办?
@youqingkui 最好不要用global,项目大了调试起来是个大问题
@ngot session.cache具体怎么存看个人习惯。SESSION又不是JSON,是数组
@MiguelValentine 如果session做成分布式,还要进行I/O操作,蛋疼不蛋疼。海量流量的时候,会拖垮服务器的
@ngot 我这样字修改了一下,Test的两个方法再pushSeller付给,但是执行到getInfo2的时候,环境不是Test的,而是node的执行环境。
this.pushSeller = function (seller_id, title, content) {
var getInfo2 = this.getInfo;
var android2 = this.android;
db.query(
"SELECT * FROM seller_admin WHERE seller_id=?", [seller_id],
function (err, seller_admin) {
if (err) {
return console.log(err);
}
if (seller_admin.length) {
for (var i = 0; i < seller_admin.length; i++) {
(function (i) {
db.query(
"SELECT os, pushtoken FROM user WHERE uid =?", [seller_admin[i].uid],
function (err, user) {
if (err) {
return console.log(err);
}
if (user[0].pushtoken) {
if (user[0].os == 'android') {
console.log(user);
getInfo2('ANDROID', 'SHOP');
android2(user[0].pushtoken, title, content)
}
}
}
);
})(i);
}
}
}
);
}
@youqingkui 你需要用call或者apply
@youqingkui 函数的上下文this,bind,call,apply搞懂特别重要
@ngot 你看他的模型,采用SESSION做的话,明显可以减少I/O。session做在REDIS内存里,比硬盘IO快多了把。
@youqingkui GLOBAL不适合cluster
@MiguelValentine 真早这么做,会上最丑方案排行榜的
@ngot 你还真别说,我写的都是最丑最快的方案。
@MiguelValentine session维护的这些变量,你打算如何释放?
@ngot 过期啊。
@MiguelValentine 等着内存暴涨吧
@MiguelValentine 在session过期时间内,海量请求,就会把内存撑爆
@MiguelValentine 正是因为放在redis内,才会有i/o开销。除非,你服务器,数据库是单台服务器。实际情况,哪有单台的。都是集群。跑起来网络i/o,还有硬件i/o,开销很大
function Test() {
var self = this;
self.style = new Xinge.Style(4, 1, 1, 1, 0);
self.getInfo = function(os, flag) {
self.accessId = Number(process.env['XINGE_' + flag + '_' + os + '_ACCESS_ID']);
self.secretKey = process.env['XINGE_' + flag + '_' + os + '_SECRET_KEY'];
self.XingeApp = new Xinge.XingeApp(self.accessId, self.secretKey);
};
self.pushSeller = function(seller_id, title, content) {
db.query(
"SELECT * FROM seller_admin WHERE seller_id=?", [seller_id],
function(err, seller_admin) {
if (err) {
return console.log(err);
}
if (seller_admin.length) {
for (var i = 0; i < seller_admin.length; i++) {
(function(i) {
db.query(
"SELECT os, pushtoken FROM user WHERE uid =?", [seller_admin[i].uid],
function(err, user) {
if (err) {
return console.log(err);
}
if (user[0].pushtoken) {
if (user[0].os == 'android') {
console.log(user);
self.getInfo.call(self, 'ANDROID', 'SHOP');
self.android.call(self, user[0].pushtoken, title, content)
}
}
}
);
})(i);
}
}
}
);
}
}
@youqingkui 或者这样
this.pushSeller = function(seller_id, title, content) {
var getInfo2 = this.getInfo.bind(this);
var android2 = this.android.bind(this);
db.query(
"SELECT * FROM seller_admin WHERE seller_id=?", [seller_id],
function(err, seller_admin) {
if (err) {
return console.log(err);
}
if (seller_admin.length) {
for (var i = 0; i < seller_admin.length; i++) {
(function(i) {
db.query(
"SELECT os, pushtoken FROM user WHERE uid =?", [seller_admin[i].uid],
function(err, user) {
if (err) {
return console.log(err);
}
if (user[0].pushtoken) {
if (user[0].os == 'android') {
console.log(user);
getInfo2('ANDROID', 'SHOP');
android2(user[0].pushtoken, title, content)
}
}
}
);
})(i);
}
}
}
);
}
@ngot 说的好像硬盘IO不要网络IO一样。还不如内存IO了