[英]node.js - mutual variable
我是node.js的新手,所以在發布我的node.js應用之前,我需要確保它能夠正常工作。
假設我有一個數組變量,並且在我的腳本開始時將其初始化
myArray = [];
然后我從外部API中提取一些數據,將其存儲在myArray中,並使用setInterval()方法每30分鍾再次提取此數據:
pullData();
setInterval(pullData, 30*60*1000);
pullData()函數大約需要2-3秒才能完成。
客戶端將能夠使用此函數獲取myArray:
http.createServer(function(request, response){
var path = url.parse(request.url).pathname;
if(path=="/getdata"){
var string = JSON.stringify(myArray);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end(string);
}
}).listen(8001);
所以我要問的是,下一種情況會發生嗎?:客戶端試圖從這個node.js服務器獲取數據,同時,數據被pullData()函數寫入myArray,導致數據無效送到客戶端?
我讀了一些文檔,我意識到當pullData()運行時,createServer()在pullData()完成其工作之前不會響應客戶端? 我真的不擅長理解並發編程,所以我需要你的確認,或者你有更好的解決方案嗎?
編輯:這是我的pullData()函數的代碼:
var now = new Date();
Date.prototype.addDays = function(days){
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
}
var endDateTime = now.addDays(noOfDays);
var formattedEnd = endDateTime.toISOString();
var url = "https://api.mindbodyonline.com/0_5/ClassService.asmx?wsdl";
soap.createClient(url, function (err, client) {
if (err) {
throw err;
}
client.setEndpoint('https://api.mindbodyonline.com/0_5/ClassService.asmx');
var params = {
"Request": {
"SourceCredentials": {
"SourceName": sourceName,
"Password": password,
"SiteIDs": {
"int": [siteIDs]
}
},
"EndDateTime" : formattedEnd
}
};
client.Class_x0020_Service.Class_x0020_ServiceSoap.GetClasses(params, function (errs, result) {
if (errs) {
console.log(errs);
} else {
var classes = result.GetClassesResult.Classes.Class;
myArray = [];
for (var i = 0; i < classes.length; i++) {
var name = classes[i].ClassDescription.Name;
var staff = classes[i].Staff.Name;
var locationName = classes[i].Location.Name;
var start = classes[i].StartDateTime.toISOString();
var end = classes[i].EndDateTime.toISOString();
var klasa = new Klasa(name,staff,locationName,start,end);
myArray.push(klasa);
}
myArray.sort(function(a,b){
var c = new Date(a.start);
var d = new Date(b.start);
return c-d;
});
string = JSON.stringify(myArray);
}
})
});
不,NodeJs不是多線程的,並且一切都在單個線程上運行,這意味着除了非阻塞調用(即IO)之外,其他所有內容都將使用CPU直到它返回,並且NodeJS絕對不會返回中途填充的數組最終用戶, 只要您只進行一次HTTP調用來填充數組 。
更新:正如@RyanWilcox所指出的,任何異步(非阻塞系統調用)調用都可能暗示NodeJS解釋器將函數執行中途退出並稍后返回。
一般來說:不。
JavaScript是單線程的。 當一個函數正在運行時,沒有其他功能可以。
例外情況是,如果在訪問數組值的函數之間存在延遲。
例如
var index = i;
function getNext() {
async.get(myArray[i], function () {
i++;
if (i < myArray.length) {
getNext()
}
});
}
...在這種情況下,可以在對異步函數的調用之間更新數組。
您可以通過在啟動第一個異步操作時創建陣列的深層副本來緩解這種情況。
Javascript是單線程語言,因此您不必擔心這種並發性。 這意味着不會同時執行兩部分代碼。 與許多其他編程語言不同,javascript具有基於事件循環的不同並發模型。 要獲得最佳性能,您應該使用由回調函數,promise或事件處理的非阻塞操作。 我想你的外部API提供了一些非常適合node.js的異步i / o函數。
如果您的pullData調用不會花費太長時間,另一種解決方案是緩存數據。
僅在需要時獲取數據(因此當客戶端訪問/ getdata時)。 如果已獲取,則可以使用時間戳緩存數據。 如果再次調用/ getdata,請檢查緩存的數據是否超過30分鍾,如果是這樣再次獲取。
還將數組解析為json ..
var string = JSON.stringify(myArray);
..可以在/ getdata調用之外完成,因此不必為訪問/ getdata的每個客戶端執行此操作。 可能會稍微快點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.