Node.JS 中的 Webworker 线程

Webworker-threads in Node.JS

本文关键字:线程 Webworker 中的 JS Node      更新时间:2023-09-26

我是来自C#世界的NodeJS新手,仍在尝试理解复杂的JavaScript迷宫。我正在尝试从 https://www.npmjs.com/package/webworker-threads 上的示例实现多线程。

无法理解为什么以下工作:

var Worker = require('webworker-threads').Worker;
var FibCalculator = require('./FibCalculator.js');
require('http').createServer(function (req,res) {
  console.log('request received.');
  var fibo = new Worker(function() {
    var calcFib = function (n) {
      return n > 1 ? calcFib(n - 1) + calcFib(n - 2) : 1;
    };
    this.onmessage = function (event) {
      postMessage(calcFib(event.data));
    };
  });
  fibo.onmessage = function (event) {
    var msg = 'fib(5) = ' + event.data;
    console.log(msg);
    res.end(msg);
  };
  fibo.postMessage(5);
}).listen(3000);

但以下就是没有

var Worker = require('webworker-threads').Worker;
var FibCalculator = require('./FibCalculator.js');
//the below function just does not get called
var calcFib = function (n) {
    console.log('***This will not print. Can someone explain why?***');
    return n > 1 ? calcFib(n - 1) + calcFib(n - 2) : 1;
};
require('http').createServer(function (req,res) {
  console.log('request received.');
  var fibo = new Worker(function() {    
    this.onmessage = function (event) {
      postMessage(calcFib(event.data));
    };
  });
  fibo.onmessage = function (event) {
    var msg = 'fib(5) = ' + event.data;
    console.log(msg);
    res.end(msg);
  };
  fibo.postMessage(5);
}).listen(3000);

为什么如果我去掉calcFib的范围,它就不能被调用。我的想法是在 webworker 线程上实现一个包装器,可用于在另一个线程上执行任何 CPU 内部操作。但是,我什至无法调用外部函数

以下是对本杰明·格伦鲍姆的回答:

如何调用控制台.log 在消息中,而不是在同一文件中的范围外定义的函数?

this.onmessage = function (event) {
  console.log('can call console.log even if it is external');
  //cannot call calcFib(event.data) if it is defined outside the scope.
  postMessage(calcFib(event.data));
};

工作人员通过复制代码来工作,以便丢失所有闭包数据。您无法从工作线程内部访问闭包范围,因此calcFib未定义。

您需要在工作线程代码定义calcFib或通过消息发送并eval它。

var Worker = require('webworker-threads').Worker;
var FibCalculator = require('./FibCalculator.js');
require('http').createServer(function (req,res) {
  console.log('request received.');
  var fibo = new Worker(function() {    
    //the below function just does not get called
    var calcFib = function (n) {
      console.log('***This will not print. Can someone explain why?***');
      return n > 1 ? calcFib(n - 1) + calcFib(n - 2) : 1;
    };
    this.onmessage = function (event) {
      postMessage(calcFib(event.data));
    };
  });
  fibo.onmessage = function (event) {
    var msg = 'fib(5) = ' + event.data;
    console.log(msg);
    res.end(msg);
  };
  fibo.postMessage(5);
}).listen(3000);

我是node-webworker-threads项目的合作者。

为什么你的代码不起作用

node-webworker-threads必须向员工传授他们被要求执行的所有功能。它们存在于单独的命名空间中,因此即使您特别告诉它们,否则它们即使在同一个文件中也无法看到存在的内容。你告诉他们使用node-webworker-threadsloadeval API的必要功能。

node-webworker-threads员工可以做什么

node-webworker-threads工作者可以执行本机JavaScript功能,如数组和对象,与JSON和正则表达式交互等。这些工作线程还支持一些特定于 Node .js内置,如控制台.log。这就是为什么你可以调用console.log(支持的内置),但不能调用你的函数(在worker的命名空间之外)。如其他地方所述,在某些情况下,内置 API 的node-webworker-threads实现并不完美匹配。