Javascript 为什么cheerio$变量不';不影响其他课程吗?
我在node.js上使用cheerio模块。 我知道在没有'var'关键字的函数中声明的变量是全局作用域 今天,我认识到当cheerio将http主体加载到$variable中时,该变量没有使用keyward“var”。 我没有任何问题。但我突然感到困惑。 在我看来,变量$是全局范围,所以连接到服务器的所有会话必须共享同一个变量 我认为我对javascript的概念是错误的。请让我来解决这个问题Javascript 为什么cheerio$变量不';不影响其他课程吗?,javascript,node.js,cheerio,Javascript,Node.js,Cheerio,我在node.js上使用cheerio模块。 我知道在没有'var'关键字的函数中声明的变量是全局作用域 今天,我认识到当cheerio将http主体加载到$variable中时,该变量没有使用keyward“var”。 我没有任何问题。但我突然感到困惑。 在我看来,变量$是全局范围,所以连接到服务器的所有会话必须共享同一个变量 我认为我对javascript的概念是错误的。请让我来解决这个问题 var cheerio = require('cheerio'); request(url, fu
var cheerio = require('cheerio');
request(url, function(err, resp, body){
if (err) throw err;
$ = cheerio.load(body);
});
在jQuery中,上下文是隐式的,它是
window.document
中的上下文
使用ChereIO时,可以有多个上下文,但每个实例一个,并且可以使用load
函数绑定此上下文。没有一个全局的$
,但如果需要,有几个全局的:
var $1 = cheerio.load(body);
var $2 = cheerio.load(someotherbody);
如果您没有忘记var
关键字,您自己的代码就不会那么混乱了。是的,您有一个bug:如果您“并行”处理多个请求,它们都将具有相同的上下文(事实上,这取决于,您可能会遇到比bug更糟糕的情况:一个潜在的bug,它将在以后添加一些正确的代码时意外出现)
下面是一个典型的代码,可能与您自己的代码类似:
request(url, function(err, resp, body){
if (err) throw err;
$ = cheerio.load(body);
doSomethingAsynchronous(function callback(){
answer($, resp);
});
});
在这里,当doSomethingAsynchronous
在另一个请求开始处理之前没有完成时,就会出现错误。在您的案例中,您没有看到任何bug的原因如下:
- 在执行异步操作后,不使用
,因为节点中只有一个用户线程,所以不会发生冲突$
速度足够快,因此在另一个请求开始应答之前执行doSomethingAsynchronous
- 一切都发生得如此之快(请记住:节点是快速的),以至于您从未真正处理过多个请求
- 如果将
作为参数显式传递给$
,则不会在回调中引用全局变量doSomethingAsynchronous
var cheerio = require('cheerio');
request(url, function(err, resp, body){
if (err) throw err;
var $ = cheerio.load(body);
// use $ here, you have one different instance per request, you may
// pass it, either explicitly as argument or using the closure
});
它可能会也可能不会导致bug,这取决于代码的其余部分。例如,您没有向我们展示这些请求是如何创建的。但一般来说,是的,您最好对每个请求处理程序调用使用
$
本地。这和这似乎是相关的。是的,但上下文在全局范围内,比如全局。1,全局。2,不是吗?当下一个客户端连接到服务器时,服务器仍然具有相同的全局变量。我认为当服务器非常繁忙时,服务器中可能会有多个会话。为什么没有冲突?如果您使用var
关键字,您将创建一个范围为当前范围的变量(在您的情况下是请求
调用的变量,而不是全局变量)。这里有一个问题。您今天看不到问题的主要原因是请求处理得如此之快,以至于没有两个请求并行处理(在节点中以“并行”方式处理请求也意味着您要为处理请求执行某种异步操作)。