javascript - 为什么 cheerio $ 变量不影响其他 session ?

标签 javascript node.js cheerio

我在 node.js 上使用 cheerio 模块。 而且我知道在没有“var”关键字的函数中声明的变量是全局范围的。

今天我认识到当 cheerio 将 http 主体加载到 $ 变量中时,该变量不使用键值“var”。 我对此没有任何问题。但是突然间我就糊涂了。 在我看来,变量 $ 是全局范围,因此所有连接到服务器的 session 都必须共享相同的变量。

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

var cheerio = require('cheerio');

request(url, function(err, resp, body){
  if (err) throw err;
  $ = cheerio.load(body);
});

最佳答案

在 jQuery 中,上下文是隐式的,它是 window.document 之一。

当您使用 cheerio 时,您可以有多个上下文,但每个实例一个,并且您使用 load 函数绑定(bind)此上下文。没有一个全局的 $,但如果需要的话有几个:

var $1 = cheerio.load(body);
var $2 = cheerio.load(someotherbody);

如果您没有忘记 var 关键字,您自己的代码就不会那么困惑了。是的,你有一个错误:如果你“并行”处理多个请求,它们都将具有相同的上下文(事实上,这取决于,你可能有比错误更糟糕的东西:一个潜在的错误,稍后会意外出现添加一些正确的代码)。

这是一个典型的代码,可能看起来像您自己的代码:

request(url, function(err, resp, body){
  if (err) throw err;
  $ = cheerio.load(body);
  doSomethingAsynchronous(function callback(){
      answer($, resp);
  });
});

这里,当 doSomethingAsynchronous 在开始处理另一个请求之前没有完成时,就会出现错误。在您的案例中,您没有看到任何错误的原因有以下几个:

  • 在你做了一个异步操作后你不使用$并且因为 Node 中只有一个用户线程所以不会有冲突
  • doSomethingAsynchronous 足够快,因此在开始响应另一个请求之前执行
  • 一切都发生得如此之快(记住: Node 是快速的)以至于你永远不会真正处理一个以上的请求
  • 你显式地将 $ 作为参数传递给 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
});

关于javascript - 为什么 cheerio $ 变量不影响其他 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25242671/

相关文章:

javascript - 有没有办法使用正则表达式来执行相同的图像交换功能,而不管扩展名如何?

javascript - 将查询字符串写入 HTML 文档

javascript - Google Maps KML Super-Overlay 不显示高细节缩放层

javascript - 使用 sudo 从 Node.js 运行命令

node.js - 嵌入式 Web UI 设计器

node.js socket.write() 不适用于 if 条件

javascript - React Native Navigator:仅在某些组件上显示导航栏

jquery - 使用 Cheerio 正则表达式搜索格式不良的 HTML 的叶节点

javascript - 使用 Node.js 抓取 JavaScript 生成的网站

javascript - 我可以向 Cheerio 选择器添加变量吗?