关于javascript:创建.json文件的一段代码不起作用

Piece of code that creates .json files, does not work

我有这个代码,它的功能是,我需要它从那个网站获取一些数据,apiur中的字符串。这段代码需要下载这些网站,在JSON中可以找到某些应用程序。它需要下载这些网站上的数据,并将它们存储在JSON文件中。出于某种原因,这不起作用。

我在.js文件中有这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var gamekeys = JSON.parse(fs.readFileSync('gamekeys.json'));
var jsonstring = JSON.stringify(gamekeys, null, 4);

UpdateGamePricelist();

function UpdateGamePricelist() {
    for(var i = 0;i<gamekeys.keys.length;i++) {
        appid = gamekeys.keys[i].appid;
       
        var apiurl ="http://store.steampowered.com/api/appdetails?appids="+appid;
       
        if (i < 95) {
           
            request(apiurl, function(err, response, body) {
                if (err) {
                    console.log("Error when updating game prices:" + err+"
"
);
                    return;
                }
               
                var apiresponse = JSON.parse(body);
                if (body =="") {
                    console.log("Could not find a pricelist m8");
                    return;
                }
               
                fs.writeFile("C:/Users/ahmad/Desktop/Bots/SteamKeyProfitter/gamespricelist/"+appid+".json", body, function(err) {
                    if(err) {
                        console.log("Error saving data to game pricelist:" + err);
                        return;
                    }
                    console.log("Game pricelist has been updated!");
                });
            });
        }
    }
}

我有一个json文件,这个json文件叫做gamekeys.json

这里是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
   "keys": [
            {
               "appid": 10,
               "price":0,
               "listofkeys":[],
               "game":"Counter-Strike"
            },
            {
               "appid": 20,
               "price":0,
               "listofkeys":[],
               "game":"Team Fortress Classic"
            },
            {
               "appid": 30,
               "price":0,
               "listofkeys":[],
               "game":"Day of Defeat"
            },
            {
               "appid": 40,
               "price":0,
               "listofkeys":[],
               "game":"Deathmatch Classic"
            },

它当然会继续下去(其中200万行)

为什么第一个代码不创建95个JSON文件?


问题是,您的appid对于所有writeFile调用都是相同的。

尝试改变:

1
appid = gamekeys.keys[i].appid;

到:

1
let appid = gamekeys.keys[i].appid;

您需要对所有回调进行新的绑定,否则它们都会得到相同的值(从上一个循环迭代中)。注意,var在这里不起作用,你需要let。如果在一个闭包中使用i,那么还需要使用for (let i = ...),而不是for (var i = ...)

apiurl可以用var声明,因为它的值传递给request()调用,而不是由一个闭包捕获,但是如果您使用let所有的时间,而不使用var就不必担心了。

如果你总是用'use strict';开始每一个程序(用引号),而从不使用var(用letconst代替),那么你就不会对你在这里的范围有问题,所以这是一个很好的做法,遵循和执行与linters。

这是问题之一。可能还有更多,但这肯定是其中之一。

更新

回答亚历克斯的评论"为什么他不能使用var-appid"

运行此代码:

1
2
3
4
5
6
for (var i = 0; i < 4; i++) {
  let appid = 'ID' + i;
  setTimeout(function () {
    console.log(appid);
  }, 500 * i);
}

运行这个程序:

1
2
3
4
5
6
for (var i = 0; i < 4; i++) {
  var appid = 'ID' + i;
  setTimeout(function () {
    console.log(appid);
  }, 500 * i);
}

并比较输出。

这说明了letvar之间的区别。

有关letvar之间差异的更多信息,请参阅此答案:

  • 为什么使用setTimeout函数时let和var绑定的行为不同?