为什么全局定义的数组在回调函数中将数据推送到它,在全局范围内是空的?

时间:2013-09-19 21:57:11

标签: javascript node.js request cheerio

我将一个空数组赋给全局变量artistURLs。然后我在Cheerio artistURL迭代器方法中将字符串(局部变量artistURLs)推送到.each()数组中。

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);
});

我知道artistURL已被成功推送到artistURLs,因为

console.log(artistURLs);

将在我的终端中显示已填充的数组。问题是如果我尝试在全局范围内的回调函数之外运行console.log(artistURLs);。例如

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);

因此,您可以看到我已将console.log(artistURLs);移至request()之外。出于某种原因,尝试访问全局范围中的artistURLs会返回一个空数组,就像在`request()〜中发生的所有处理从未发生过一样。

为什么会发生这种情况以及如何确保所有被推入artistURLs的网址都保留在artistURLs

由于

1 个答案:

答案 0 :(得分:1)

request()模块是异步的,因此当您使用console.log()时,在HTTP调用完成之前,console.log()正在执行。例如,请使用以下代码:

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);

你会看到这个结果:

[]
push
push
...
push
push
push

为了防止这种情况发生,只使用HTTP请求回调中的变量artistURLs