javascript - Calling asynchronous function in callback -


i'm having trouble understanding asynchronous functions. i've read chapter in mixu's node book still can't wrap head around it.

basically want request ressource (using node package cheerio), parse valid urls , add every match redis set setname.

the problem in end it's adding first match redis set.

function parse(url, setname)  {     request(url, function (error, response, body)      {         if (!error && response.statuscode == 200)          {             $ = cheerio.load(body)              // every 'a' tag in body             $('a').each(function()              {                 // add blog url redis if not there.                 var blog = $(this).attr('href')                 console.log("test [all]: " + blog);                  // filter valid urls                 var regex = /http:\/\/[^www]*.example.com\//                 var result = blog.match(regex);                 if(result != null)                  {                     console.log("test [filtered]: " + result[0]);                      redis.sismember(setname, result[0], function(err, reply)                      {                         if(!reply)                          {                             redis.sadd(setname, result[0])                             console.log("added " + result[0])                         }                         redis.quit()                         })                 }             })         }     }) } 

i'd grateful pointers on how i'd have restructure redis.sadd method working correct result.

the output of current implementation looks like:

test [all]: http://test1.example.com/ test [filtered]: http://test1.example.com/ ... added http://test2.example.com/ 

so it's adding test1.example.com not printing "added" line, , it's not adding test2.example.com it's printing "added" line it.

thank you!

the first issue caused redis.sismember() being asynchronous: when callback called, have overwritten result variable point last value had, , not value @ moment @ called redis.sismember().

one way solve create new scoped variable wrapping asynchronous function in closure:

(function(result) {   redis.sismember(setname, result[0], function(err, reply) {     ...   }); })(result); 

another option create partial function that's used callback:

  redis.sismember(setname, result[0], function(result, err, reply) {     ...   }.bind(this, result)); 

the second issue is, think, caused redis.quit() being called, closes redis connection after first sadd(). you're not checking err, if might tell more.


Comments