访问全局变量javascript

Accessing global variable javascript

本文关键字:javascript 全局变量 访问      更新时间:2023-09-26

我正在尝试使用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'
}

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

while(!downloadFinished) {
}

该循环将永远运行,并且不会运行其他函数(由于Javascript的单线程特性,在while循环完成之前,.on('complete'回调无法执行,因此它永远不会完成,因为您没有在该循环中设置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'
    });
}

当您调用那个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库,你可以添加到你的包依赖项中。