[英]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.