不能一起执行的功能
Functions that can't execute together
我最近在构建一个 scraper 模块以使用 nodejs 获取一些信息,直到我遇到这个 "little" 问题。我使用的模块是 cheeriojs 和 request。
实际上,如果我一次只调用一个方法,该模块就像一个魅力。它包含三个函数,其中只有两个是导出的,这是代码:
'use strict';
var request = require('request'),
cheerio = require('cheerio'),
counter = 0;
function find(term, cat, callback) {
// All the check for the parameters
scrape("http://.../search.php?search=" + encodeURIComponent(term), cat, callback);
}
function last(cat, callback) {
// All the check for the parameters
scrape("http://google.com/", cat, callback);
}
function scrape(url, cat, callback) {
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(body);
var result = [];
var items = $('.foo, .foo2').filter(function() {
// Condition to filter the resulted items
});
items.each(function(i, row) {
// Had to do another request inside here to scrape other information
request( $(".newpagelink").attr("href"), function(error, response, body) {
var name = $(".selector").text(),
surname = $(".selector2").text(),
link = cheerio.load(body)('.magnet').attr('href'); // This is the only thing that I'm scraping from the new page, the rest comes from the other "cheerio.load"
// Push an object in the array
result.push( { "name": name, "surname": surname, "link": link } );
// To check when the async requests are ended
counter++;
if(counter == items.length-1) {
callback(null, result);
}
});
});
}
});
}
exports.find = find;
exports.last = last;
正如我所说,现在的问题是,如果我创建一个新的节点脚本 "test.js" 并且我只调用 last OR find,它会完美运行!但是如果我像这样连续调用这两种方法:
var mod = require("../index-tmp.js");
mod.find("bla", "blabla", function(err, data) {
if (err) throw err;
console.log(data.length + " find");
});
mod.last(function(err, data) {
console.log(data.length + " last");
});
结果一团糟,有时脚本甚至不打印任何东西,有时只打印 "find" 或 "last" 的结果,有时 returns cheeriojs 错误(我不会在此处添加以免打扰您,因为这可能是我脚本的错误)。我还想为这两种方法重复相同的功能两次,但没有,同样的问题发生了......我不知道还能尝试什么,我希望你能告诉我这种行为的原因!
您的 counter
变量是全局变量,并非特定于每个 scrape
调用。如果您同时调用 find
两次,或者 last
.
,它也不会起作用
将 var counter = 0;
的声明和初始化移动到 scrape
函数中,或者更好的是紧挨着 result
和 items
声明。
通过快速扫描您的代码,这可能是由于变量 counter
是全局的。这些是异步函数,因此它们将同时作用于 counter
。将声明移到 scrape
函数中。
如果您需要有关异步编程的更多信息,请参阅 this question 中 Felix 的精彩回答。
我最近在构建一个 scraper 模块以使用 nodejs 获取一些信息,直到我遇到这个 "little" 问题。我使用的模块是 cheeriojs 和 request。 实际上,如果我一次只调用一个方法,该模块就像一个魅力。它包含三个函数,其中只有两个是导出的,这是代码:
'use strict';
var request = require('request'),
cheerio = require('cheerio'),
counter = 0;
function find(term, cat, callback) {
// All the check for the parameters
scrape("http://.../search.php?search=" + encodeURIComponent(term), cat, callback);
}
function last(cat, callback) {
// All the check for the parameters
scrape("http://google.com/", cat, callback);
}
function scrape(url, cat, callback) {
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(body);
var result = [];
var items = $('.foo, .foo2').filter(function() {
// Condition to filter the resulted items
});
items.each(function(i, row) {
// Had to do another request inside here to scrape other information
request( $(".newpagelink").attr("href"), function(error, response, body) {
var name = $(".selector").text(),
surname = $(".selector2").text(),
link = cheerio.load(body)('.magnet').attr('href'); // This is the only thing that I'm scraping from the new page, the rest comes from the other "cheerio.load"
// Push an object in the array
result.push( { "name": name, "surname": surname, "link": link } );
// To check when the async requests are ended
counter++;
if(counter == items.length-1) {
callback(null, result);
}
});
});
}
});
}
exports.find = find;
exports.last = last;
正如我所说,现在的问题是,如果我创建一个新的节点脚本 "test.js" 并且我只调用 last OR find,它会完美运行!但是如果我像这样连续调用这两种方法:
var mod = require("../index-tmp.js");
mod.find("bla", "blabla", function(err, data) {
if (err) throw err;
console.log(data.length + " find");
});
mod.last(function(err, data) {
console.log(data.length + " last");
});
结果一团糟,有时脚本甚至不打印任何东西,有时只打印 "find" 或 "last" 的结果,有时 returns cheeriojs 错误(我不会在此处添加以免打扰您,因为这可能是我脚本的错误)。我还想为这两种方法重复相同的功能两次,但没有,同样的问题发生了......我不知道还能尝试什么,我希望你能告诉我这种行为的原因!
您的 counter
变量是全局变量,并非特定于每个 scrape
调用。如果您同时调用 find
两次,或者 last
.
将 var counter = 0;
的声明和初始化移动到 scrape
函数中,或者更好的是紧挨着 result
和 items
声明。
通过快速扫描您的代码,这可能是由于变量 counter
是全局的。这些是异步函数,因此它们将同时作用于 counter
。将声明移到 scrape
函数中。
如果您需要有关异步编程的更多信息,请参阅 this question 中 Felix 的精彩回答。