javascript - `bind` 如何与 `Meteor.bindEnvironment` 一起使用?

标签 javascript node.js meteor

我对 bindMeteor.bindEnvironment 的行为以及 this 的作用域有点困惑Meteor.bindEnvironment。例如,with arrow functions, arrow functions should maintain the outer scope :

Essentially it allows you to create an anonymous function with the contextual value of “this” being the scope of the function being that of the outer function that the arrow function is being defined in.

所以,当我使用以下代码时,它似乎可以工作,但是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的回调中使用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 绑定(bind)到函数?有正确的用法吗?

最佳答案

什么是箭头函数?

这是一个确实令人困惑且冗长的句子:

Essentially it allows you to create an anonymous function with the contextual value of “this” being the scope of the function being that of the outer function that the arrow function is being defined in.

通过将其压缩为更简洁的语言可以使其更容易理解:

It allows you to create an anonymous function that is bound lexically to the scope in which it is defined.

________

Arrow Functions解释

您提供的示例中没有 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 对象,则箭头函数将按词法绑定(bind)到 Meteor 对象:

// this instanceof Meteor === true
let socket = net.connect(connection, Meteor.bindEnvironment(() => {
    console.log(this instanceof Meteor); // => 'true'
}));

________

bind方法解释

让我们讨论一下为什么要使用 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

绑定(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接受给定的函数并将其绑定(bind)到由闭包维护的执行上下文,bindEnvironment 方法最初是在该闭包中定义的。

An explanation of the purpose of Meteor.bindEnvironment on GitHub :

The idea of bindEnvironment is so that, when passing callbacks to non-Meteor code, you can keep them running in the current context. On the server that includes the current fiber. So if you're finding yourself outside of a Fiber on the server, you're probably not calling bindEnvironment enough!

通过给它一个已经绑定(bind)的函数(作为箭头函数或通过手动绑定(bind)函数),您可以防止它更改函数的执行上下文。

关于javascript - `bind` 如何与 `Meteor.bindEnvironment` 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32822823/

相关文章:

javascript - 在 Javascript 中从数组创建列表

javascript - 相当于 Internet Explorer 中的 "parentNode"

javascript - 使用 jQuery 动态添加行

javascript - 如何用 promise 关闭文件句柄?

node.js - Nodejs部署的应用程序中的环境变量

javascript - 为什么我的调试控制台调试已关闭的旧文件而不是当前文件?

node.js - AWS 有没有办法隐藏我的nodejs 代码,同时向我的客户公开与访问和存储相关的账单信息

css - Bootstrap 包在 Meteor 中不起作用

meteor - 如何在工作的 Meteor 项目上实现 Collection2?

ubuntu - 访问 docker 内的二进制文件