如何使用`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.bindEnvironmentcallback中使用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函数),都可以防止它改变函数的执行上下文。