简体   繁体   English

Twitch API使用Array.map()以错误的顺序返回信息

[英]Twitch API returning info in wrong order using Array.map()

I'm calling the Twitch API (should mention I'm doing this in React) to get information on a few channels. 我正在调用Twitch API(应该在React中这样做)来获取一些渠道的信息。 I'm getting the data back, but it gets added to the array in the wrong order, different on every reload. 我正在取回数据,但是它以错误的顺序添加到阵列中,每次重新加载时都不同。 Since I have two make two different calls, this ends up leaving me with mismatched information. 由于我有两个打两个不同的电话,因此最终给我留下了不匹配的信息。 I'm assuming it's because some calls take longer than other, and array.map() is running regardless if the first call was done yet, I'm just not sure how to fix that. 我假设这是因为某些调用比其他调用花费的时间更长,并且无论第一个调用是否完成,array.map()都在运行,我不确定该如何解决。

Here is my script: 这是我的脚本:

export default class TwitchApp extends React.Component {
state = {
    games: [],
    statuses: [],
    names: [],
    logos: [],
    streams: ["nl_kripp", "ESL_SC2", "Day9tv", 
    "DisguisedToastHS" ]
};
findStreams = () => {
    const channels = this.state.streams;
    const statusUrls = channels.map((channel) => {
        return 'https://api.twitch.tv/kraken/streams/' + channel;
    }) 

    const infoUrls = channels.map((channel) => {
        return 'https://api.twitch.tv/kraken/channels/' + channel;
    })
    statusUrls.map((statusUrl)=> {
        let url = statusUrl;
        return $.ajax({
            type: 'GET',
            url: url,
            headers: {
                'Client-ID': 'rss7alkw8ebydtzisbdbnbhx15wn5a' 
            },
            success: function(data) {
                        let game;
                        let status = data.stream != null ? "Offline" : "Online";
                        this.setState((prevState)=> ( { statuses: prevState.statuses.concat([status]) } ) );
                        status = '';
            }.bind(this)
        });
    });
    infoUrls.map((url)=> {
        return $.ajax({
            type: 'GET',
            url: url,
            headers: {
                'Client-ID': 'rss7alkw8ebydtzisbdbnbhx15wn5a' 
            },
            success: function(data) {
                  let name = data.display_name != null ? data.display_name : 'Error: Can\'t find channel';
                  let logo = data.logo != null ? data.logo : "https://dummyimage.com/50x50/ecf0e7/5c5457.jpg&text=0x3F";
                  let game = data.game != null ? data.game : "Offline";
                  //let status = data.status != null ? data.status: "Offline";
                  this.setState((prevState)=> ( {  games: prevState.games.concat([game]), names: prevState.names.concat([name]), logos: prevState.logos.concat([logo]) } ) );
                  game = '';
                  logo = '';
                  name = '';
             }.bind(this)
        }); 
    }); 
};

You have really many options here... 您在这里有很多选择...

  1. could either look into AsyncJs and it is the async.series(); 可以研究AsyncJs ,它就是async.series(); you are looking for, that will make all call go into specific order. 您正在寻找,这将使所有呼叫进入特定的顺序。

  2. You could also go for a promised based HTTP requester, like Axios in which you can chain all your requests. 您还可以使用基于承诺的HTTP请求程序,例如Axios ,您可以在其中链接所有请求。

But really, I would go with the 3rd option which is that you make an array of objects as your state like this: 但实际上,我会选择第3个选项,即您将对象阵列做成这样的状态:

state = {
    info: {
        "nl_kripp": {
            game: '',
            status: '',
            name: '',
            logo: '',
        },
        "ESL_SC2": {
            game: '',
            status: '',
            name: '',
            logo: '',
        },
        "Day9tv": {
            game: '',
            status: '',
            name: '',
            logo: '',
        },
        "DisguisedToastHS": {
            game: '',
            status: '',
            name: '',
            logo: '',
        }
    },
    streams: ["nl_kripp", "ESL_SC2", "Day9tv", "DisguisedToastHS"]
};

and do something like this: 并执行以下操作:

var streams = this.state.streams;
var fetchedArray = [];
fetchedArray.map(streams , stream => {
    let url = 'https://api.twitch.tv/kraken/streams/' + stream;
    return $.ajax({
        type: 'GET',
        url: url,
        headers: {
            'Client-ID': 'rss7alkw8ebydtzisbdbnbhx15wn5a' 
        },
        success: function(data) {
            var currentState = Object.assign({}, this.state.info[stream]);
            currentState.status = data.stream === null ? 'Offline' : 'Online';
            currentState.name = data.display_name;
            currentState.logo = data.channel.logo;
            currentState.game = data.game;
        }.bind(this)
    });
});

Now fetchedArray will hold the same information but stacked together and easily handle with javascript after, rather than unsorted arrays. 现在, fetchedArray将保存相同的信息,但将它们堆叠在一起,并可以轻松地使用javascript之后的代码来处理,而不是使用未排序的数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM