简体   繁体   English

node.js - 互变量

[英]node.js - mutual variable

I'm new to node.js, so before releasing my node.js app, I need to be sure it will work as it should. 我是node.js的新手,所以在发布我的node.js应用之前,我需要确保它能够正常工作。

Let's say I have an array variable and I intialize it on beginning of my script 假设我有一个数组变量,并且在我的脚本开始时将其初始化

myArray = [];

then I pull some data from an external API, store it inside myArray, and use setInterval() method to pull this data again each 30 minutes: 然后我从外部API中提取一些数据,将其存储在myArray中,并使用setInterval()方法每30分钟再次提取此数据:

pullData();
setInterval(pullData, 30*60*1000);

pullData() function takes about 2-3 seconds to finish. pullData()函数大约需要2-3秒才能完成。

Clients will be able to get myArray using this function: 客户端将能够使用此函数获取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);

So what I'm asking is, can next situation happen?: An client tries to get data from this node.js server, and in that same moment, data is being written into myArray by pullData() function, resulting in invalid data being sent to client? 所以我要问的是,下一种情况会发生吗?:客户端试图从这个node.js服务器获取数据,同时,数据被pullData()函数写入myArray,导致数据无效送到客户端?

I read some documentation, and what I realized is that when pullData() is running, createServer() will not respond to clients until pullData() finishes its job? 我读了一些文档,我意识到当pullData()运行时,createServer()在pullData()完成其工作之前不会响应客户端? I'm really not good at understanding concurrent programming, so I need your confirmation on this, or if you have some better solution? 我真的不擅长理解并发编程,所以我需要你的确认,或者你有更好的解决方案吗?

EDIT: here is the code of my pullData() function: 编辑:这是我的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);
     }
        })


    });

No, NodeJs is not multi-threaded and everything run on a single thread, this means except non-blocking calls (ie. IO) everything else will engage CPU until it returns, and NodeJS absolutely doesn't return half-way populated array to the end user, as long as you only do one HTTP call to populate your array . 不,NodeJs不是多线程的,并且一切都在单个线程上运行,这意味着除了非阻塞调用(即IO)之外,其他所有内容都将使用CPU直到它返回,并且NodeJS绝对不会返回中途填充的数组最终用户, 只要您只进行一次HTTP调用来填充数组

Update: As pointed out by @RyanWilcox any asynchronous (non-blocking syscall) call may hint NodeJS interpreter to leave your function execution half way and return to it later. 更新:正如@RyanWilcox所指出的,任何异步(非阻塞系统调用)调用都可能暗示NodeJS解释器将函数执行中途退出并稍后返回。

In general: No. 一般来说:不。

JavaScript is single threaded. JavaScript是单线程的。 While one function is running, no other function can be. 当一个函数正在运行时,没有其他功能可以。

The exception is if you have delays between functions that access the value of an array. 例外情况是,如果在访问数组值的函数之间存在延迟。

eg 例如

var index = i;
function getNext() {
    async.get(myArray[i], function () {
        i++;
        if (i < myArray.length) {
            getNext()
        }
    });
}

… in which case the array could be updated between the calls to the asynchronous function. ...在这种情况下,可以在对异步函数的调用之间更新数组。

You can mitigate that by creating a deep copy of the array when you start the first async operation. 您可以通过在启动第一个异步操作时创建阵列的深层副本来缓解这种情况。

Javascript is single threaded language so you don't have to be worried about this kind of concurrency. Javascript是单线程语言,因此您不必担心这种并发性。 That means no two parts of code are executed at the same time. 这意味着不会同时执行两部分代码。 Unlike many other programming languages, javascript has different concurrency model based on event loop . 与许多其他编程语言不同,javascript具有基于事件循环的不同并发模型。 To achieve best performance, you should use non-blocking operations handled by callback functions, promises or events. 要获得最佳性能,您应该使用由回调函数,promise或事件处理的非阻塞操作。 I suppose that your external API provides some asynchronous i/o functions what is well suited for node.js. 我想你的外部API提供了一些非常适合node.js的异步i / o函数。

If your pullData call doesn't take too long, another solution is to cache the data. 如果您的pullData调用不会花费太长时间,另一种解决方案是缓存数据。

Fetch the data only when needed (so when the client accesses /getdata). 仅在需要时获取数据(因此当客户端访问/ getdata时)。 If it is fetched you can cache the data with a timestamp. 如果已获取,则可以使用时间戳缓存数据。 If the /getdata is called again, check if the cached data is older than 30 minutes, if so fetch again. 如果再次调用/ getdata,请检查缓存的数据是否超过30分钟,如果是这样再次获取。

Also parsing the array to json.. 还将数组解析为json ..

var string = JSON.stringify(myArray);

..might be done outside the /getdata call, so this does not have to be done for each client visiting /getdata. ..可以在/ getdata调用之外完成,因此不必为访问/ getdata的每个客户端执行此操作。 Might make it slightly quicker. 可能会稍微快点。

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

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