【问题标题】:Unable to Access Object from a jQuery JSONP Call (JavaScript)无法从 jQuery JSONP 调用 (JavaScript) 访问对象
【发布时间】:2018-04-12 01:56:58
【问题描述】:

这是我将两个 JSON 对象推入数组后的数据示例。访问数据很简单。如果我想访问说徽标,我可以使用example[0].channels.logo。但是,当尝试通过 JSONP 调用访问相同的数组时,结果为 undefined

let example =
[
    {
    "channels": {
        "mature": false,
        "status": "Some GoLang Today #go #golang #youtube",
        "broadcaster_language": "en",
        "display_name": "FreeCodeCamp",
        "game": "Creative",
        "language": "en",
        "_id": 79776140,
        "name": "freecodecamp",
        "created_at": "2015-01-14T03:36:47Z",
        "updated_at": "2018-04-11T22:33:06Z",
        "partner": false,
        "logo": "https://static-cdn.jtvnw.net/jtv_user_pictures/freecodecamp-profile_image-d9514f2df0962329-300x300.png",
        "video_banner": "https://static-cdn.jtvnw.net/jtv_user_pictures/freecodecamp-channel_offline_image-b8e133c78cd51cb0-1920x1080.png",
        "profile_banner": "https://static-cdn.jtvnw.net/jtv_user_pictures/freecodecamp-profile_banner-6f5e3445ff474aec-480.png",
        "profile_banner_background_color": null,
        "url": "https://www.twitch.tv/freecodecamp",
        "views": 210806,
        "followers": 11582,
        "_links": {
        "self": "https://api.twitch.tv/kraken/channels/freecodecamp",
        "follows": "https://api.twitch.tv/kraken/channels/freecodecamp/follows",
        "commercial": "https://api.twitch.tv/kraken/channels/freecodecamp/commercial",
        "stream_key": "https://api.twitch.tv/kraken/channels/freecodecamp/stream_key",
        "chat": "https://api.twitch.tv/kraken/chat/freecodecamp",
        "features": "https://api.twitch.tv/kraken/channels/freecodecamp/features",
        "subscriptions": "https://api.twitch.tv/kraken/channels/freecodecamp/subscriptions",
        "editors": "https://api.twitch.tv/kraken/channels/freecodecamp/editors",
        "teams": "https://api.twitch.tv/kraken/channels/freecodecamp/teams",
        "videos": "https://api.twitch.tv/kraken/channels/freecodecamp/videos"
        },
        "delay": null,
        "banner": null,
        "background": null
      }
    },
    {
    "streams": {
        "stream": null,
        "_links": {
        "self": "https://api.twitch.tv/kraken/streams/freecodecamp",
        "channel": "https://api.twitch.tv/kraken/channels/freecodecamp"
        }
      }
    }
]

// all of these work
console.log(example);
console.log(example[0]);
console.log(example[0].channels);
console.log(example[0].channels);

这是处理每个 JSONP 请求的函数 - 每个响应都存储在一个对象中,该对象具有定义的路由参数的属性名称。

const jsonpCall = (route, channel) => {
    let result = {};
    $.ajax({
        url: `https://wind-bow.gomix.me/twitch-api/${route}/${channel}?callback=?`,
        dataType: 'jsonp',
        success: function(data){
            result[route] = data;
        },
    });
    return result;
};

这是一个函数调用,它将两个返回的对象分组到一个数组中,然后将该数组交给另一个函数来排序/归约到一个对象。

const channelsToSearch = ["freecodecamp","nba","shroud"];

channelsToSearch.forEach(channel => {
    const channelData = [];
    channelData.push(jsonpCall("channels",channel));
    channelData.push(jsonpCall("streams",channel));
    console.log(sortData(channelData));
});

这就是问题的开始。此函数获取两个对象的数组,并开始创建一个新对象以返回。它无法访问该对象。

const sortData = arr =>  {
    console.log(arr); // okay!
    console.log(arr[0]); // okay!
    console.log(arr[0].channels); // undefined?
    const obj = {};
    obj.logo        = arr[0].channels.logo;
    obj.displayName = arr[0].channels["display_name"];
    arr[1].streams.stream === null ? obj.status = "Offline" : obj.status = arr[1].streams.stream.channel.status;
    return obj;
};

我不确定从日志中的差异中可以看出什么。 前三个日志来自示例日志。 最后三个日志来自 sortData 函数。 最后一个错误来自 sortData 函数中的obj.logo = arr[0].channels.logo; 行。

【问题讨论】:

标签: javascript jquery json ajax object


【解决方案1】:

这段代码的问题在于这部分:

const jsonpCall = (route, channel) => {
    let result = {};
    $.ajax({
        url: `https://wind-bow.gomix.me/twitch-api/${route}/${channel}?callback=?`,
        dataType: 'jsonp',
        success: function(data){
            result[route] = data;
        },
    });
    return result;
};

ajax 调用是异步的,但它被视为同步的。这就是为什么它将返回 {} 的结果,因为 success 函数执行较晚。如果您尝试在success 函数中添加console.log,您会看到它会出现在sortData. 内的日志之后,这就是为什么在您的日志中,它显示Array [{}, {}],它们都是空的。

解决这个问题的一种方法是异步编码:

确保jsonpCall 返回Promise。默认情况下$.ajax() 返回一个Promise

在这部分代码中:

channelsToSearch.forEach(channel => {
    const channelData = [];
    channelData.push(jsonpCall("channels",channel));
    channelData.push(jsonpCall("streams",channel));
    console.log(sortData(channelData));
});

您必须使用.then 回调异步处理它。

请看这个小提琴:https://jsfiddle.net/kLnsf1gn/2。为了便于理解,我在其中添加了 cmets。

【讨论】:

    猜你喜欢
    • 2017-05-08
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    相关资源
    最近更新 更多