I have a function:
var third = function(classes){
for (var i = 0; i <= (classes.length-1); i++) {
var Myurl = classes[i];
return function(Myurl){
request(Myurl, function(err, resp, body) {
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(body);
$("#item_details dl").each(function() {
var Values = [];
var New = [];
Values=$(this).find("dd strong").text();
New = Values.replace(/[\n\t\r]/g,"");
AllLinks.push(New);
});
console.log(AllLinks);
};
})
}(MyUrl);
};
};
The problem is when I do the above I only get the result of first loop element (i=0)
in the console.log(AllLinks)
. How do I properly loop in node? I am new to node so any ments are much appreciated!
EDIT:
If I define AllLinks
in request
then it seems to work, but not in correct order...
var third = function(classes){
for (var i = 0; i <= (classes.length-1); i++) {
var Myurl = classes[i];
(function(Myurl){
request(Myurl, function(err, resp, body) {
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(body);
AllLinks=[];
$("#item_details dl").each(function() {
var Values = [];
var New = [];
Values=$(this).find("dd strong").text();
New = Values.replace(/[\n\t\r]/g,"");
AllLinks.push(New);
});
console.log(AllLinks);
}(Myurl);
})
};
};
};
I have a function:
var third = function(classes){
for (var i = 0; i <= (classes.length-1); i++) {
var Myurl = classes[i];
return function(Myurl){
request(Myurl, function(err, resp, body) {
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(body);
$("#item_details dl").each(function() {
var Values = [];
var New = [];
Values=$(this).find("dd strong").text();
New = Values.replace(/[\n\t\r]/g,"");
AllLinks.push(New);
});
console.log(AllLinks);
};
})
}(MyUrl);
};
};
The problem is when I do the above I only get the result of first loop element (i=0)
in the console.log(AllLinks)
. How do I properly loop in node? I am new to node so any ments are much appreciated!
EDIT:
If I define AllLinks
in request
then it seems to work, but not in correct order...
var third = function(classes){
for (var i = 0; i <= (classes.length-1); i++) {
var Myurl = classes[i];
(function(Myurl){
request(Myurl, function(err, resp, body) {
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(body);
AllLinks=[];
$("#item_details dl").each(function() {
var Values = [];
var New = [];
Values=$(this).find("dd strong").text();
New = Values.replace(/[\n\t\r]/g,"");
AllLinks.push(New);
});
console.log(AllLinks);
}(Myurl);
})
};
};
};
Share
Improve this question
edited May 26, 2015 at 10:39
user1665355
asked May 26, 2015 at 9:58
user1665355user1665355
3,3939 gold badges47 silver badges86 bronze badges
11
- async library npmjs./package/async – Callum Linington Commented May 26, 2015 at 10:01
- @CallumLinington Thanks, I am a node beginner, so you maybe can provide an example about how the above function should be changed? best regards – user1665355 Commented May 26, 2015 at 10:02
- Why do you want to return call result return function(Myurl){...}(MyUrl);? In certain scenarios it might be enough. Otherwise you might want to try promises or async library – Igor Popov Commented May 26, 2015 at 10:03
- @Igor how do you mean? – user1665355 Commented May 26, 2015 at 10:06
- I'm not sure how you implement request but if you drop 'return' you'll most likely be able to call all your urls from classes. If you want to wait for all calls to succeed async.js sounds like your choice. – Igor Popov Commented May 26, 2015 at 10:09
3 Answers
Reset to default 4The major problem (apart from 'return') is that assuming request performs asyncronous operation your function returns when request is not pleted and thus log contains no update.
You have two strategies in general:
- call your code without 'return' as in the example above. This case all your requests will be eventually done but you have no control over when. It works well when you don't need them all to proceed, e.g. process AllLinks afterwards
- Use any technology that supports waiting until all your calls are pleted (async.js or promises). For example here Simplest way to wait some asynchronous tasks plete, in Javascript?
Thus you need:
function appendResultToItems(url, callback) {
request(url, function(err, resp, body) {
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(body);
$("#item_details dl").each(function() {
var Values = [];
var New = [];
Values=$(this).find("dd strong").text();
New = Values.replace(/[\n\t\r]/g,"");
AllLinks.push({result:New, url: url});
callback();
});
});
}
var calls = [];
classes.forEach(function(Myurl){
calls.push(function(callback) {
appendResultToItems(Myurl, callback);
});
});
async.parallel(calls, function() {
console.log(AllLinks);
});
Use async.js#eachSeries to apply an asynchronous function to each element of a collection
Your problem is you are using return within the loop. If you simply use an IIFE
var third = function(classes){
for (var i = 0; i <= (classes.length-1); i++) {
var Myurl = classes[i];
(function(Myurl){
request(Myurl, function(err, resp, body) {
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(body);
$("#item_details dl").each(function() {
var Values = [];
var New = [];
Values=$(this).find("dd strong").text();
New = Values.replace(/[\n\t\r]/g,"");
AllLinks.push(New);
});
console.log(AllLinks);
};
})
})(MyUrl);
};
};
AllLinks
will be correctly generated.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745205115a4616557.html
评论列表(0条)