Javascript/NodeJS 回调函数和循环
Javascript/NodeJS callbacks function and loop
我用 cheerio
和 request
制作了一个网络爬虫,我现在正在尝试在 url 的数组上实现一个循环。
不幸的是,我的呼叫和回叫有问题,但我不知道是什么。
这是我的代码:
var getWebData = function(url) {
var i = 1;
var data = [];
for (c = 0; c < url.length; c++) {
data[i] = request(url[c], function(err, resp, body) {
console.log('ok');
if (!err) {
console.log('there');
var $ = cheerio.load(body);
$('.text').each(function(i, element) {
var jsObject = { name : "", description : "", price: "", categorie: "", pricePerKg: "", capacity: "", weight: "", scrapingDate : "", url: ""};
var name = 'TESTOK';
jsObject.name = name;
data.push(jsObject);
})
return data;
}
console.log('but');
});
i++;
}
var json = JSON.stringify(data);
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
console.log('File successfully written!');
})
}
getWebData(url);
app.listen('8080');
请注意,我的任何调试打印都没有打印出来。
有人知道我的代码有什么问题吗?我该怎么做才能让它工作?
请求是 Aysnc
var json = JSON.stringify(data);
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
console.log('File successfully written!');
})
上面的代码 运行s 在 for 循环完成执行并填充数据对象之前。
尝试在循环完成执行时执行这段代码。
运行 这个命令先 npm install async --save
var async = require('async');
var getWebData = function(url){
var data = [];
async.eachSeries(url, function(urlSingle , cb){
request(urlSingle, function(err, resp, body) {
//write your logic here and push data in to data object
cb();
})
},function(){
// this will rum when loop is done
var json = JSON.stringify(data);
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
console.log('File successfully written!');
});
});
}
我一直在阅读 Asif 的回答和评论。该实现是正确的,但您不必增加 c 变量,而且,如果您之前启动 c=0,所有请求都将发送到 url[0].
注意async.eachSeries在"urlsingle"回调中回调数组url的每个元素,所以你应该使用
request(urlsingle, ...
或考虑使用 async.eachOf,它会为您提供数组中每个元素的索引。
检查异步文档是否有任何疑问http://caolan.github.io/async/
for (c = 0; c < url.length; c++) {
……
}
你应该这样改:
var async = require('asycn');
async.map(url,
function(item, callback) {
data[i] = request(url[c],
function(err, resp, body) {
console.log('ok');
if (!err) {
console.log('there');
var $ = cheerio.load(body);
$('.text').each(function(i, element) {
var jsObject = {
name: "",
description: "",
price: "",
categorie: "",
pricePerKg: "",
capacity: "",
weight: "",
scrapingDate: "",
url: ""
};
var name = 'TESTOK';
jsObject.name = name;
data.push(jsObject);
}) callback(err, data);
}
console.log('but');
});
i++;
},function(err, results) {
if(err){
console.log(err);
}
});
在循环中比较耗时operation.you应该使用异步操作
我用 cheerio
和 request
制作了一个网络爬虫,我现在正在尝试在 url 的数组上实现一个循环。
不幸的是,我的呼叫和回叫有问题,但我不知道是什么。
这是我的代码:
var getWebData = function(url) {
var i = 1;
var data = [];
for (c = 0; c < url.length; c++) {
data[i] = request(url[c], function(err, resp, body) {
console.log('ok');
if (!err) {
console.log('there');
var $ = cheerio.load(body);
$('.text').each(function(i, element) {
var jsObject = { name : "", description : "", price: "", categorie: "", pricePerKg: "", capacity: "", weight: "", scrapingDate : "", url: ""};
var name = 'TESTOK';
jsObject.name = name;
data.push(jsObject);
})
return data;
}
console.log('but');
});
i++;
}
var json = JSON.stringify(data);
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
console.log('File successfully written!');
})
}
getWebData(url);
app.listen('8080');
请注意,我的任何调试打印都没有打印出来。
有人知道我的代码有什么问题吗?我该怎么做才能让它工作?
请求是 Aysnc
var json = JSON.stringify(data);
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
console.log('File successfully written!');
})
上面的代码 运行s 在 for 循环完成执行并填充数据对象之前。 尝试在循环完成执行时执行这段代码。
运行 这个命令先 npm install async --save
var async = require('async');
var getWebData = function(url){
var data = [];
async.eachSeries(url, function(urlSingle , cb){
request(urlSingle, function(err, resp, body) {
//write your logic here and push data in to data object
cb();
})
},function(){
// this will rum when loop is done
var json = JSON.stringify(data);
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) {
console.log('File successfully written!');
});
});
}
我一直在阅读 Asif 的回答和评论。该实现是正确的,但您不必增加 c 变量,而且,如果您之前启动 c=0,所有请求都将发送到 url[0].
注意async.eachSeries在"urlsingle"回调中回调数组url的每个元素,所以你应该使用
request(urlsingle, ...
或考虑使用 async.eachOf,它会为您提供数组中每个元素的索引。
检查异步文档是否有任何疑问http://caolan.github.io/async/
for (c = 0; c < url.length; c++) {
……
}
你应该这样改:
var async = require('asycn');
async.map(url,
function(item, callback) {
data[i] = request(url[c],
function(err, resp, body) {
console.log('ok');
if (!err) {
console.log('there');
var $ = cheerio.load(body);
$('.text').each(function(i, element) {
var jsObject = {
name: "",
description: "",
price: "",
categorie: "",
pricePerKg: "",
capacity: "",
weight: "",
scrapingDate: "",
url: ""
};
var name = 'TESTOK';
jsObject.name = name;
data.push(jsObject);
}) callback(err, data);
}
console.log('but');
});
i++;
},function(err, results) {
if(err){
console.log(err);
}
});
在循环中比较耗时operation.you应该使用异步操作