我在 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/