繁体   English   中英

node.js - 互变量

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

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