Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么cheerio$变量不';不影响其他课程吗?_Javascript_Node.js_Cheerio - Fatal编程技术网

Javascript 为什么cheerio$变量不';不影响其他课程吗?

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

我在node.js上使用cheerio模块。 我知道在没有'var'关键字的函数中声明的变量是全局作用域

今天,我认识到当cheerio将http主体加载到$variable中时,该变量没有使用keyward“var”。 我没有任何问题。但我突然感到困惑。 在我看来,变量$是全局范围,所以连接到服务器的所有会话必须共享同一个变量

我认为我对javascript的概念是错误的。请让我来解决这个问题

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
关键字,您将创建一个范围为当前范围的变量(在您的情况下是
请求
调用的变量,而不是全局变量)。这里有一个问题。您今天看不到问题的主要原因是请求处理得如此之快,以至于没有两个请求并行处理(在节点中以“并行”方式处理请求也意味着您要为处理请求执行某种异步操作)。