如何使用`Meteor.bindEnvironment`绑定?
我有点困惑与Meteor.bindEnvironment
bind
的行为,以及与Meteor.bindEnvironment
的范围。 例如, 使用箭头函数,箭头函数应该保持外部范围 :
从本质上讲,它允许你创build一个匿名函数,其上下文值是“this”,这个函数的作用域就是定义箭头函数的外部函数的作用域。
所以,当我使用下面的代码,它似乎工作,但console.log
似乎说this
是meteor的范围。
Cylon = new EventEmitter(); Cylon.messages = new Mongo.Collection('_cylon_messages'); Cylon._commands = net.connect(Settings.connection); Cylon._createConnection = function (name, connection) { let socket = net.connect(connection, Meteor.bindEnvironment(() => { this.messages.insert({ name: name, message: 'connected'}) })); socket._name = name; return socket; }
另一个我一直不理解的例子是在需要Meteor.bindEnvironment
callback中使用bind。 例如:
Cylon.execute = function (routine) { check(command, String); let future = new Future(); let done = future.resolver(); this.once('End', Meteor.bindEnvironment(done.bind(null, routine))); this._commands.write(`XQ#${routine}\r`, 'utf8'); future.wait(); this.removeListener('End', Meteor.bindEnvironment(done.bind(null, routine))); return future; }
Meteor.bindEnvironment
如何与this
绑定到一个函数? 有适当的用法吗?
什么是箭头function?
这是一个非常混乱和冗长的句子:
从本质上讲,它允许你创build一个匿名函数,其上下文值是“this”,这个函数的作用域就是定义箭头函数的外部函数的作用域。
通过把它凝结成更简洁的语言,可以使它更容易理解:
它允许您创build一个匿名函数,该函数与其定义的作用域词法绑定。
________
箭头function解释
在你提供的例子中没有console.log
,可能你在给bindEnvironment
的箭头函数中放了一个console.log
,如下所示:
let socket = net.connect(connection, Meteor.bindEnvironment(() => { console.log(this); // this.messages.insert({ name: name, message: 'connected'}); }));
事实上,在上面的例子中, this
是对箭头函数的执行上下文的引用。 例如:
this.stillInScope = true; let socket = net.connect(connection, Meteor.bindEnvironment(() => { console.log(this.stillInScope); // => 'true' }));
但是,假设我们将箭头函数改为匿名函数。 在调用时,它不会保持对声明时出现的执行上下文的访问:
this.stillInScope = true; let socket = net.connect(connection, Meteor.bindEnvironment(function () { console.log(this.stillInScope); // => 'undefined' }));
所以,如果这个例子的当前执行上下文是Meteor对象,那么箭头函数将被从词汇上绑定到Meteor对象:
// this instanceof Meteor === true let socket = net.connect(connection, Meteor.bindEnvironment(() => { console.log(this instanceof Meteor); // => 'true' }));
________
bind
方法的解释
让我们来讨论一下为什么你会使用bind
来理解你的第二个例子中所取得的成果。
bind
第一个参数:执行上下文
在一个方法上使用bind
会产生一个绑定到由第一个参数定义的执行上下文的新函数。 比方说,我们在全局执行上下文是window
的浏览器中运行它:
let method = function () { console.log(this); }; method(); // => window let boundMethod = method.bind('Hello'); // `this` now becomes 'Hello' boundMethod(); // => 'Hello'
这个绑定永远不能改变; 而不是通过绑定函数中的调用,或者通过随后的bind
调用。
后续参数bind
:默认参数
在你给定的例子中, bind
实际上只是被用作简写。 我们可以知道这是因为给定的执行上下文为null
,表明bind
仅用于将缺省参数应用于函数的方式:
// with `bind` Meteor.bindEnvironment(done.bind(null, routine)) // without `bind` Meteor.bindEnvironment(function () { done(routine); });
________
bind
如何与Meteor.bindEnvironment
工作?
最后,为了回答你的问题, bind
本身并不与任何东西一起工作。 Meteor.bindEnvironment
将给定的函数绑定到一个由闭包维护的执行上下文,其中最初定义了bindEnvironment
方法。
Meteor.bindEnvironment
在GitHub上的目的解释 :
bindEnvironment的思想是,当将callback传递给非Meteor代码时,可以让它们保持在当前的上下文中运行。 在包含当前光纤的服务器上。 所以如果你发现自己在服务器上的光纤之外,你可能不会调用bindEnvironment了!
通过给它一个已经绑定的函数(无论是作为一个箭头函数还是传递一个手动bind
函数),都可以防止它改变函数的执行上下文。