javascript - webworker-theads 中的关闭
问题描述
当我在 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 函数无法访问其闭包。
同样在这个例子中,为什么不允许工作函数访问它的闭包?因为只有一个函数想要访问 let counter=0
解决方案
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. 通常在任何需要新作用域的地方(需要隐藏一些东西)
由于函数是操作范围的唯一机制,因此您还需要使用闭包来创建范围。这在安全关键代码中特别有用,例如处理需要与 3rd 方库交互的身份验证和金融交易的代码。
2.1。节点模块
Node.js 专门使用闭包来实现 javascript 中不存在的东西:文件范围。
node 中的模块被加载到 IIFE 中,从而创建了一个闭包。模块文件中的所有变量对文件中定义的所有函数(闭包)都是可见的,但对其他模块不可见(除非声明时没有var
,let
或const
)。Ryan Dahl 不想将 Javascript 作为一种语言进行修改,而只是在该语言之上添加一个框架以使其在浏览器之外有用。幸运的是,Javascript 足够强大(有闭包),这是可能的。
现实世界的例子
有几个大规模使用闭包的真实例子:
React.FunctionComponent
是 React.js 中的一项最新功能,它允许用户使用闭包来实现 React 组件而不是类。这通常会减少代码行数和复杂性(是的,这与前端更相关,但规模非常大)async.js
大量使用闭包来跟踪异步操作Express.js
是混合的。虽然大部分代码都是面向对象的,但它也使用闭包,尤其是在中间件/路由架构中。
推荐阅读
- c# - 如何对从较大的 XDocument 中提取的 XElement 执行 XPath 选择?
- javascript - 当我向选定列中的单元格添加值时,我希望它复制到另一个 Google 表格
- css - 在可变大小的框中调整图像大小并保持纵横比
- python - 交互式绘图 Jupyter Lab 2.0
- android - JSON 格式的 Android Volley 数组
- reactjs - 成帧器运动 | 在最后一个动画加载后视点“useAnimation”触发
- c# - SqlException:INSERT 语句与使用 EF 代码优先 C# 的 FOREIGN KEY 约束冲突
- javascript - 为什么我无法填充帖子字段?
- javascript - 根据当前月份打开特定选项卡
- python - Python:递归获取二维数组的排列