How come a globally defined array that gets data pushed to it with in a callback function is empty in the global scope?

StackOverflow https://stackoverflow.com/questions/18905605

문제

I assign an empty array to the global variable artistURLs. I then push strings (the local variable artistURL) into the artistURLs array with in the Cheerio .each() iterator method.

var request = require('request'),
  cheerio = require('cheerio'),
  url = 'http://www.primarytalent.com/',
  artistURLs = [];

request(url, function(err, resp, body){
  if(err)
    throw err;
  $ = cheerio.load(body);
  $('#rosterlists div li a').each(function(){
    var urlCap = this.attr('href').slice(1);
    var artistURL = url.concat(urlCap);
    artistURLs.push(artistURL);
  });
  console.log(artistURLs);
});

I know that artistURL is successfully being pushed into artistURLs because

console.log(artistURLs);

will display the populated array in my terminal. The problem is if I try running console.log(artistURLs); outside of the callback function in the global scope. For example

var request = require('request'),
  cheerio = require('cheerio'),
  url = 'http://www.primarytalent.com/',
  artistURLs = [];

request(url, function(err, resp, body){
  if(err)
    throw err;
  $ = cheerio.load(body);
  $('#rosterlists div li a').each(function(){
    var urlCap = this.attr('href').slice(1);
    var artistURL = url.concat(urlCap);
    artistURLs.push(artistURL);
  });
});

console.log(artistURLs);

So you can see that I have moved console.log(artistURLs); outside of request(). For some reason trying to access artistURLs in the global scope returns me an empty array as if all the processing that happened with in `request()~ never even happened.

How come this is happening and how can ensure that all the urls that are being pushed into artistURLs remain in artistURLs?

Thanks

도움이 되었습니까?

해결책

The request() module is asynchronous, so console.log() is executing before the HTTP call completes when you use console.log(). For example, take this code:

var request = require('request');
var cheerio = require('cheerio');
var url = 'http://www.primarytalent.com/';
var artistURLs = [];

request(url, function(err, resp, body){
  if (err)
    throw err;
  $ = cheerio.load(body);
  $('#rosterlists div li a').each(function(){
    var urlCap = this.attr('href').slice(1);
    var artistURL = url.concat(urlCap);
    artistURLs.push(artistURL);
    console.log('push');
  });
});

console.log(artistURLs);

You will see this result:

[]
push
push
...
push
push
push

To prevent this from happening, only use the variable artistURLs inside of the HTTP request callback.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top