访问全局变量javascript

时间:2014-04-10 22:15:55

标签: javascript node.js

我正在尝试使用nodejs,javascript下载网页。然而它似乎有一个无限循环。为什么呢?

var downloadFinished = false;

var downloadPage = function(url,file) {
  rest.get(url).on('complete', function(result) {
  if (result instanceof Error) {
    console.log('Error:', result.message);
  } else {
    fs.writeFileSync(file, result, 'utf8');
    downloadFinished = true;
   }   
  }); 
};

if(require.main == module) {
    downloadPage('http://google.com', 'new.html');
    while(!downloadFinished) {
       // wait till download finished.
    } 
    // do other stuff make sure download is finished to 'new.html'
}

2 个答案:

答案 0 :(得分:4)

Javascript是单线程的,如果你有一个循环:

while(!downloadFinished) {

}

该循环将继续运行并且不会运行其他函数(由于Javascript的单线程特性,你的.on('complete'回调在while循环完成之前无法执行,所以它永远不会完成因为你没有在该循环中设置downloadFinished = true或使用break语句。)

要解决此问题,您可以在回调中完成所有其他内容,直到下载完成后才能调用:

var downloadPage = function(url, file, callback) {
  rest.get(url).on('complete', function(result) {
    if (result instanceof Error) {
      console.log('Error:', result.message);
    } else {

      /* Don't use writeFileSync, unless you want to block your server,
        from handling any requests at all until the disk IO completes

        fs.writeFileSync(file, result, 'utf8');
        callback();
      */
      fs.writeFile(file, result, 'utf8', callback);
    }   
  }); 
};

if(require.main == module) {
    downloadPage('http://google.com', 'new.html', function after_download(){
        // do other stuff make sure download is finished to 'new.html'
    });
}

答案 1 :(得分:1)

当您致电while(!downloadFinished)时,它会设置为false,因此您基本上正在执行while(true)

选项1

您可以使用回调而不是while循环。

var successCallback = function() {
 //do stuff here.
};

var downloadPage = function(url, file, callback) {
  rest.get(url).on('complete', function(result) {
  if (result instanceof Error) {
    console.log('Error:', result.message);
  } else {
    fs.writeFile(file, result, 'utf8', callback);
   }   
  }); 
};

if(require.main == module) {
    downloadPage('http://google.com', 'new.html', successCallback);
}

选项2

查看Promises他们真的会帮到你。您可以使用Bluebird一个很好的Promise库,只需添加到包依赖项中即可。