我在node.js上使用cheerio模块。 我知道在没有'var'关键字的函数中声明的变量是全局范围。
今天我认识到当cheerio将http body加载到$ variable时,变量不会使用keyward'var'。 我没有遇到任何问题。但突然间我感到困惑。 在我看来,变量$是全局范围,因此连接到服务器的所有会话必须共享相同的变量。
我认为我的javascript概念错了。请让我解决这个问题。
var cheerio = require('cheerio');
request(url, function(err, resp, body){
if (err) throw err;
$ = cheerio.load(body);
});
答案 0 :(得分:2)
在jQuery中,上下文是隐式的,它是window.document
的上下文。
当您使用cheerio时,您可以拥有多个上下文,但每个实例一个上下文,并使用load
函数绑定此上下文。没有全球$
,但如果需要,还有几个:
var $1 = cheerio.load(body);
var $2 = cheerio.load(someotherbody);
如果您没有忘记var
关键字,那么您自己的代码就不那么容易混淆了。是的,你有一个错误:如果你在" parallel"中处理了几个请求。他们都有相同的上下文(实际上它取决于你,你可能会遇到比bug更糟糕的事情:一个潜在的错误,在添加一些正确的代码后会出乎意料地出现)。
这是一个典型的代码,可能看起来像你自己的代码:
request(url, function(err, resp, body){
if (err) throw err;
$ = cheerio.load(body);
doSomethingAsynchronous(function callback(){
answer($, resp);
});
});
这里,当doSomethingAsynchronous
在另一个请求开始处理之前没有完成时会出现错误。在你的案例中,有几个原因导致您没有看到任何错误:
$
因为节点中只有一个用户线程没有冲突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
});