繁体   English   中英

node.js,可以外部请求改变正在运行的函数中的变量

[英]node.js, can external request alter variables in a running function

我已经设置了一个节点服务器来保存日志信息。 预计会有非常大量的请求进入。我正在使用mongo数据存储,但这种性能太不可靠了。 阅读报告方面的数据通常需要很长时间。 所以我切换到经典的mysql。 如果您准备批量插入而不是单独插入,则显然存在显着的写入吞吐量优势。 所以我找到了这个人:

https://gist.github.com/3078520

我喜欢它的简单性。 这是一些线条,非常强大。 它有两个主要函数add() ,它们将向队列添加一条记录,然后在队列达到一定大小时调用flush() 然后它有flush()将队列连接成一个长字符串并创建一个长批量插入语句,然后发送到mysql驱动程序(我从提供的链接简化了函数:

this.flush = function () {
/*1*/    var sql = queryTemplate.replace('{values}', '\n('+ queue.join('),\n(') +')');
/*2*/    handle.query(sql, callback);
/*3*/    queue = [];
}

这本质上是一个类函数,它是请求处理程序拥有的单个类实例的一部分。 所以我的问题是,这样安全吗? queue是一个类变量。 调用flush() ,它会处理队列。 我能看到的唯一问题是如果调用flush() ,执行第1行来生成sql语句(只是一个字符串), 然后调用另一个add()来向queue添加一些东西,然后第一个进程调用query()函数然后清空队列。 在这种情况下,第二个进程添加的记录将丢失,因为第一个进程在创建sql语句时不会知道它,并在清除queue时将其擦除。 这可能吗?

这个问题的更一般化的形式如下。 一旦函数开始执行,外部的其他任何东西都可以影响其范围之外的变量吗? 这是一个非常简单的示例,在此示例中是否可以执行console.log,假设不同的请求调用这两个函数:

var global_number;
function a(){
  global_number=2;
}
function b(){
  global_number=1;
  if(global_number==2){
    console.log("a() influenced global_number in the middle of b()'s execution")
  }
}

这主要是一个是/否的问题,但我正在寻找更多的东西。 一个简短的解释或链接到我可以了解更多的页面将是伟大的! 谢谢!

如果函数是同步的,那么在函数开始执行和完成函数之间,没有任何东西可以影响该函数引用的变量。

但是,如果函数调用异步函数(例如MySQL查询),则函数本身是异步的,其他代码可以在函数运行的时间和异步函数的回调时间之间修改函数的父/全局范围中的变量。运行。

是的,如果函数的执行是异步的,那么您可能对全局变量拥有的数据有问题。 这是测试场景;

var globalVariable = 10;

function a ()
{
    var timer = setInterval(function() {
        globalVariable--;
        console.log(globalVariable)
    }, 1000);
}

function b ()
{
    setTimeout(function() {
        globalVariable = 20;
    }, 3000);
}

a();
b();

这将是:

9
8
7
19
18
17
16

如果你要求执行中断,这不是异步,没办法! 查看示例。

var globalVariable = 1000000000;
function a () {
    for(var i=0; i < 1000000000; i++)
    {
        if(globalVariable == 20000) console.log('From a() : ' + globalVariable);
        globalVariable--;
        if(globalVariable == 0) break;
    }
}

function b () {
    setTimeout(function() {
        console.log('From b() : ' + globalVariable);
        globalVariable = 20000;
        console.log('From b() : ' + globalVariable);
    }, 1);
}

b();
a();

这将始终输出:

From a() : 20000
From b() : 0
From b() : 20000

所以,你的问题答案是否定的,你不能中断同步功能的执行。

然而; 在你的代码片段示例中,似乎可以清空queue因为你已经在第1行使用queue.join消耗queue的数据。另一方面,这种方法会受到回滚操作的影响。 例如,当sql返回错误时,您可能无法重新填充queue

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM