用于Node.js中的闭包?

时间:2019-06-13 06:44:08

标签: javascript node.js closures

我知道闭包是什么。通过在内部函数(外部函数)中插入内部函数并在外部函数内部返回内部函数,可以使全局变量成为局部变量。

我一直试图深入了解javascript和node.js的工作方式。由于闭包非常重要,并且对我来说很难理解该术语(因为我的母语不是英语),所以我花了很多时间在它上面。所有的文章或网站都一直在用简单的“计数器”功能教授闭包,但是我一直在Node.js中寻找真实的例子。

当我在node.js中研究工作线程时,我遵循了“ webworker-threads” npm软件包网站上的说明,并且我实现了以下错误代码。那让我重新考虑关闭。

const express = require("express");
const app = express();
const Worker = require("webworker-threads").Worker;
app.get("/", (req, res) => {
  //   let counter = 0; // if i put this here code is not working
  const worker = new Worker(function() {
    this.onmessage = function() {
      let counter = 0;
      while (counter < 1000000) {
        counter = counter + 1;
      }
      this.postMessage(counter);
    };
  });
  worker.onmessage = function(result) {
    console.log(result);
    res.send(result);
  };
  worker.postMessage();
});
app.get("/fast", (req, res) => {
  res.send("this is fast");
});
app.listen(3100, () => {
  console.log("listening");
});

由于错误,我将let counter=0放在了worker函数之外,但是服务器挂起并且无法加载。然后,我将其放在worker函数中尝试不同的方法,并且成功了。

我相信我终于在node.js中看到了一个有关闭包的示例。但是我该怎么形容呢?这是正确的吗?

Worker函数无法访问其闭包。

在此示例中,为什么为什么不允许工作者函数访问其关闭?因为只有一个功能要访问 让counter = 0

2 个答案:

答案 0 :(得分:2)

1。面向对象编程的替代方法

理论上,您可以在任何可以使用类/构造函数的地方使用闭包代替。它们本质上都执行相同的事情:封装数据并维护状态-但通过不同的机制。对象使用上下文维护状态(Java称其为“作用域”,但是因为Java实际上没有真正的作用域),而闭包使用作用域进行维护。

关闭对于替换单方法类(这令人惊讶地有很多用途)特别有用:

让我们看一个简单的文件记录器。 OO实现可以是:

class Logger {
    constructor (filename) {
        this.logfile = fs.openSync(filename,'a');
        this.log.bind(this);
    }

    log (txt) {
        const now = new Date().toISOString();
        fs.write(this.logfile, `${now} : ${txt}\n`);
    }
}

// usage:
const logger = new Logger('file.log');
logger.log('Hello');

可以使用闭包代替实现相同的逻辑:

function makeLogger (filename) {
    const logfile = fs.openSync(filename,'a');

    return function (txt) {
        const now = new Date().toISOString();
        fs.write(logfile, `${now} : ${txt}\n`); // <-- using closure here!
    }
}

// usage:
const log = makeLogger('file.log');
log('Hello');

取决于与谁交谈,闭包实现更易于阅读(我是对闭包比对类更满意的人之一)。它不仅更短,而且还包含状态,并且不能从其他代码更改。

2。通常在任何需要新作用域的地方(需要隐藏一些东西)

由于函数是操作范围的唯一机制,因此您还需要使用闭包来创建范围。这在安全性至关重要的代码中尤其有用,例如与身份验证和金融交易相关的代码,这些代码需要与第三方库进行交互。

2.1。节点模块

Node.js专门使用闭包来实现javascript:文件作用域中不存在的东西。

节点中的模块被加载到IIFE中,从而创建了一个闭包。模块文件中的所有变量对于文件中定义的所有函数(关闭)均可见,而其他模块则不可见(除非声明时未使用varletconst除外)。 Ryan Dahl不想将Javascript修改为一种语言,而只是在该语言之上添加一个框架以使其在浏览器中有用。幸运的是,JavaScript足够强大(有闭包),这是可能的。

现实世界中的例子

在闭包的大规模使用中,有几个真实的例子:

  • React.FunctionComponent是React.js的最新功能,允许用户使用闭包来实现React组件而不是类。这通常可以减少代码行和复杂性(是的,这与前端相关,但是规模非常大)

  • async.js经常使用闭包来跟踪异步操作

  • Express.js混合了。虽然大多数代码都是面向对象的,但它也使用闭包,尤其是在中间件/路由体系结构中。

答案 1 :(得分:-1)

闭包是函数和在其中声明该函数的词法环境的组合。因此,内部函数即使在外部函数返回后也可以访问外部函数的变量。 现在,当我们进入其应用程序时,我们知道node.js不支持访问说明符,隐式闭包使我们能够做到这一点 下面是相同的示例:

a = (function () {
  var privatefunction = function () {
    alert('hello');
  }

  return {
    publicfunction : function () {
        privatefunction();
    }
  }
})();