意外的全局变量行为

时间:2019-07-27 06:47:57

标签: javascript variables global

有人可以帮助我提供此代码吗?为简化起见,简化了该问题,因为变量myGlobalVar的行为不像全局变量。

var request = require('request');
var myGlobalVar = "myglobalstring";
var options = {
  url: 'https://api.github.com/repos/request/request',
  headers: {
    'User-Agent': 'request'
  }
};

function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    var info = JSON.parse(body);
    myGlobalVar = info.stargazers_count + " Stars";
    console.log(myGlobalVar + "-1");
  }
  //myGlobalVar = info.stargazers_count + " Stars";
  // console.log(myGlobalVar+"-2");
}
request(options, callback);
console.log(myGlobalVar + "-3")

结果是

myglobalstring-3

23038 Stars-1

23038 Stars-2 (Uncommenting those lines)

变量不会将值保留在函数之外...

2 个答案:

答案 0 :(得分:0)

您需要了解的是,request是一个异步函数调用,它在后台进行了REST API调用,并在稍后的时间间隔接收到响应,然后执行回调函数。因此,当您调用request时,执行流程会立即转到下一行而不等待响应,并显示myglobalstring-3

要解决此问题,您需要将console.log(myGlobalVar + "-3")移动到回调函数中。像这样

var request = require('request');
var myGlobalVar = "myglobalstring";
var options = {
  url: 'https://api.github.com/repos/request/request',
  headers: {
    'User-Agent': 'request'
  }
};

function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    var info = JSON.parse(body);
    myGlobalVar = info.stargazers_count + " Stars";
    console.log(myGlobalVar + "-1");
  }
  //myGlobalVar = info.stargazers_count + " Stars";
  // console.log(myGlobalVar+"-2");

    // Now it should print the value you expect
    myGlobalVar = info.stargazers_count + " Stars";
    console.log(myGlobalVar + "-3")
}
request(options, callback);

另一种方法是使用promisesasync/await。 使用此axios,或者如果您更喜欢request,则使用request-promises

这是一篇介绍promisesasync/await的文章, https://stackabuse.com/node-js-async-await-in-es7/

答案 1 :(得分:0)

myGlobalVar的行为与代码中的全局变量完全相同。您可能想要的是控制台语句,以-1,-2,-3之类的顺序打印。为此,您需要了解javascript中的异步函数。 请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

只是为了证明myGlobalVar在请求后确实分配了最后一个值,请在下面查看对您的代码所做的更改。我们正在调用setTimeout函数以查看5秒钟后myGlobalVar包含的内容(假设在该时间范围内已经发出了请求)。

var request = require('request');
var myGlobalVar = "myglobalstring";
var options = { url: 'https://api.github.com/repos/request/request', headers: {'User-Agent': 'request'}};
function callback(error, response, body) 
{
if (!error && response.statusCode == 200) 
{
var info = JSON.parse(body);
myGlobalVar = info.stargazers_count + " Stars";
console.log(myGlobalVar+"-1");
}
myGlobalVar = info.stargazers_count + " Stars";
console.log(myGlobalVar+"-2");
}
request(options, callback);           
setTimeout(function(){
   console.log(myGlobalVar+"-3");
},5000);

这将为您提供如下输出

"23038 Stars-1"
"23038 Stars-2"
"23038 Stars-3"

您也可以在https://runkit.com/5d3bf6ac32e3bb001467a45d/5d3bf6ad59cbcf0015d00af3

进行检查