在请求函数中推送一些数据后,为什么数组变得不确定?

时间:2018-07-09 11:19:10

标签: javascript arrays node.js scope request

我使用FACEIT API从某个匹配项中获取5个昵称。我想使用这5个昵称并将它们存储在players数组中,然后重用它来创建5个新的url,这将使我能够为每个玩家获取更多信息。问题是在将昵称推送到players数组后,我只会得到undefined

var express = require("express");
var app = express();
var request = require('request');

var players = [];

var headers = {
    'Accept': 'application/json',
    'Authorization': 'Bearer <my API code which I don't want to display>'
};

var options = {
    url: 'https://open.faceit.com/data/v4/matches/cdc61c3b-2f9b-4c92-a2c9-ea1cfb54eb51',
    headers: headers
};

request(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var parsedBody = JSON.parse(body);
        for (var i = 0; i < 5; i++) {
            players.push(parsedBody["teams"]["faction1"]["roster_v1"][i]["nickname"]);
        }
    }
});

var options2 = {
    // I get "https://open.faceit.com/data/v4/players?nickname=undefined" instead of 
    // "https://open.faceit.com/data/v4/players?nickname=lonely52"
    url: "https://open.faceit.com/data/v4/players?nickname=" + players[0], 
    headers: headers
};

request(options2, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var parsedBody = JSON.parse(body);
        console.log(parsedBody["nickname"]); // UNDEFINED
    }
});

app.get("/", function(req, res) {
    res.send(players);  // ["lonely52","Crowned","pstarbang","wolf1E_KZ","Fr0let"]
});

app.listen(3000, function() {
    console.log("Listening on port 3000...");
});

2 个答案:

答案 0 :(得分:0)

我认为您的请求编号2是在请求1有时间推送到变量之前完成的。您应该将所有这些请求包装到一个大型异步函数中。等待他们。这样的事情:

        async function myreq()
        {
           let j = await request(options, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var parsedBody = JSON.parse(body);
                for (var i = 0; i < 5; i++) {
                    players.push(parsedBody["teams"]["faction1"]["roster_v1"][i]["nickname"]);
                }
            }
        });

        var options2 = {
            // I get "https://open.faceit.com/data/v4/players?nickname=undefined" instead of 
            // "https://open.faceit.com/data/v4/players?nickname=lonely52"
            url: "https://open.faceit.com/data/v4/players?nickname=" + players[0], 
            headers: headers
        };

        request(options2, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var parsedBody = JSON.parse(body);
                console.log(parsedBody["nickname"]); // UNDEFINED
            }
        });
    }

myreq();

答案 1 :(得分:0)

原因: 您正在进行异步的REST API调用。甚至在您从“玩家列表” API得到响应之前,就会调用“玩家详细信息” API。因此,在发出请求时,数组中没有任何内容,并且player[0]undefined

解决方案:

在您收到“玩家列表” API的响应后,只需在其回调中调用“玩家详细信息” API即可:

request(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var playerList = JSON.parse(body);
        for (var i = 0; i < 5; i++) {
            var nickname = playerList["teams"]["faction1"]["roster_v1"][i]["nickname"]);

            var options2 = {
                url: "https://open.faceit.com/data/v4/players?nickname=" + nickname, 
                headers: headers
            };

            request(options2, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    var playerDetails = JSON.parse(body);
                    console.log(playerDetails["nickname"]); // UNDEFINED
                }
            });
        }
    }
});

在这里,您甚至不必将播放器名称放入数组中,就可以立即发出请求。
这应该完成工作。

替代项:
还有其他方法可以实现此目的,例如使用async-await或使用async.js或每次您从第一个API获得响应,将数据推送到数组中以及获得所有响应后就递增计数器,请调用一个将遍历数组的函数,并在所有这些函数上调用第二个API。

PS::研究一下nodejs callbacks,它们很有趣,可以帮助您解决此类问题。