无法在函数内调用非内置函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法在函数内调用非内置函数相关的知识,希望对你有一定的参考价值。

我的代码中有问题 - 我的代码中有一部分做了很多计算(30~40秒)

我需要尽可能地减少这个时间 - 所以我必须利用我的所有CPU线程并分发这部分以便更快地完成

几天 - 我做了很多关于如何在nodejs中编写多线程代码的研究和搜索,我传递了很多关于nodejs如何是单线程或多线程的意见,并且关于一些主题如聚类,孩子 - 工人和工人..

我更喜欢使用一个现成的库来不深入研究这些主题,所以我尝试了这个库:https://github.com/Microsoft/napajs,但它解决了我的一些问题。

我想要的应该是简单的 - 我只有数组(准备并行计算 - 每个线程准备好在每个元素上工作)[数据,数据,数据,数据]

我发现这个库:https://www.npmjs.com/package/paralleljs有点简单,有这个方法(地图),这对我的情况很好

让我们转到我的代码

初始化

var p = new Parallel([54,25,66,23,14,27,15,18] , { maxWorkers : 8 });

3个函数(fun是调用exports.calc和calc的主要函数)

exports.calc = function(i,h)
{
    return Math.log2(i*h);
}

function calcc(i,h)
{
    return Math.log2(i*h);
}

function fun(h)
{
    var sum = 0;
   for (var i = 1 ; i < 55555 ; i++)
   {
       for (var l = 1 ; l < 55555 ; l++)
       {
           sum+=(exports.calc(i,l)); // in this case calc is not a function error
           sum+=(calcc(i,l)); // in this case calcc is not defined error
       }
   } 
   return sum;
}

使用map函数启动并行计算 - 此函数应该分割数组,让每个线程分别处理每个元素

p.map(fun).then(data => {
        console.log(data);
    });

这个错误总是很有趣 - 任何时候都试图调用非内置函数 - 例如

Math.max(),String.includes()等等,所有这些内置函数都没有出现任何问题,但是任何非内置函数(如calcc和exports.calc)都会产生问题

根据库文档,它使用子进程 - 如果这可以帮助,

如果您无法解决此问题 - 但有其他方法可以使此代码成为可能(与任何其他库) - 请分享

答案

这可以通过Node cluster实现:

var cluster = require('cluster');

function calcc(i,h) {
    return Math.log2(i*h);
}

function fun(h) {
   var sum = 0;
   for (var i = 1 ; i < 5555 ; i++) {
       for (var l = 1 ; l < 5555 ; l++) {
           sum+=(calcc(i,l));
           sum+=(calcc(i,l));
       }
   } 
   return sum;
}

if (cluster.isMaster) {   
  var CPU = 8;    
  var count = 0;

  function messageHandler(msg) {
    console.log(msg);
    count++;
    if (count == CPU)
      console.log('Complete');
  }

  for (let i = 0; i < CPU; i++) {
    var worker = cluster.fork();
    worker.on('message', messageHandler);
  }    
} else if (cluster.isWorker) {
  process.send(fun());
}

由于集群用于网络连接,因此可以提供一些开销,因此使用child_process.fork()(由cluster使用)的低级实现可能更有效。

节点10及更高版本有实验节点worker threads

另一答案

我从未使用过并行,但基于行为以及如何使用它,我认为@estus基本上是正确的。

如果函数本身被传递 - >它不会带来任何有关以前环境的信息。

您需要在函数初始化初始化您使用的所有内容。

最直接的方法是将它放在main函数中:

function fun(h)
{
    const calc = function(){...}
}

最优雅的是在里面使用require。所以把你想要分享的所有内容放到另一个模块中,然后导出它就行了

function fun(h)
{
    const tools = require('tools');
    tools.calc(...)
}

以上是关于无法在函数内调用非内置函数的主要内容,如果未能解决你的问题,请参考以下文章

函数内置方法

无法调用非函数类型 HTTPURLResponse 的值?

无法在 Swift 3 中调用非函数类型“UICollectionView”的值

无法调用非函数类型“HTTPURLResponse”的值?

无法调用非函数类型“URL”的值

绑定与非绑定方法及反射,isinstance和issubclass内置函数