简体   繁体   English

JavaScript:如何正确遍历数组并将值用作键?

[英]JavaScript: How to properly loop through array and use values as keys?

I am getting a JSON-string from a remote endpoint and want to use values as keys. 我从远程端点获取JSON字符串,并希望将值用作键。 So I am looping through the result like that: 所以我正在遍历这样的结果:

(function() {
// Create the connector object
var myConnector = tableau.makeConnector();

var definitions = [];

// Define the schema
myConnector.getSchema = function(schemaCallback) {

$.ajax({
    url: apiUrl,
    type: 'GET',
    crossDomain: true,
    cache: false,
    headers: {
        'X-Auth-Token':'123',
        'X-Auth-User':'user1'
    },
    dataType: "json",
    success: function(response){

        $.each(response,function(key,value){

                console.log("inside loop");
                console.log(value);
                definitions[value.id]
                     = value.name;

        }); 

        console.log("inside ajax");
        console.log(definitions);
    }

});

console.log("done");
console.log(definitions);

// this is where I want to loop through my result
// whithout success (no console output
for (var key in definitions) {
        console.log(key);

    }

}; //     myConnector.getSchema = function(schemaCallback) {

})(); //function() {

This is the response from the API: 这是来自API的响应:

[
{
    "id": 123,
    "name": "Name1"
},
{
    "id": 456,
    "name": "Name2"
},
{
    "id": 789,
    "name": "Name3"
}]

This is the output of the first log command, inside the loop: 这是循环内第一个log命令的输出:

{id: 123, name: "Name1"}
id: 123
name: "Name1"
__proto__: Object

The problem is, the last log looks like this: 问题是,最后一个日志如下所示:

[123: "Name1", 456: "Name3", 789: "Name4"]
123: "Name1"
456: "Name2"
789: "Name3"
length: 0
__proto__: Array(0)

The problem is clearly: The array length is shown as zero. 问题很明显:数组长度显示为零。 And this I do not understand. 我不明白这一点。

Later in this script I want to loop through this array again, but because of this strange result, I am not able to address the index keys. 在此脚本的后面,我想再次遍历该数组,但是由于这个奇怪的结果,我无法处理索引键。

What is it, that I am doing wrong? 我做错了什么事?

Additional information 附加信息

I am working on a web connector for Tableau that will connect to an RESTful service's endpoint. 我正在为Tableau开发Web连接器,该连接器将连接到RESTful服务的端点。 Unfortunately I cannot publish the actual RESTful URL, because it provides private data. 不幸的是,我无法发布实际的RESTful URL,因为它提供了私有数据。

I am using this simulator: http://tableau.github.io/webdataconnector/Simulator/ 我正在使用此模拟器: http : //tableau.github.io/webdataconnector/Simulator/

I added all the surroundings to the upper source code. 我将所有环境添加到上层源代码中。 There are few more lines of source code, but it's absolutely not related to my work (one more different loop and variable definitions). 源代码很少,但绝对与我的工作无关(还有另一种不同的循环和变量定义)。

I now tried the script in Firefox (Chrome before). 现在,我在Firefox(以前的Chrome)中尝试了该脚本。 The only result I get here is 我得到的唯一结果是

done myConnector.js:97:5
[]
​
length: 0
​
<prototype>: Array []

All the other console.log's are not triggered. 其他所有console.log均未触发。

Also Firefox complains about CORS, this is known because I already fixed the CORS-header server-side. Firefox也抱怨CORS,这是众所周知的,因为我已经修复了CORS标头服务器端。 But nevertheless at the end data is being received and populated to the simulator I am using (see URL above)! 但是,尽管如此 ,最后还是接收到数据并将其填充到我正在使用的模拟器中(请参见上面的URL)! Clearly I am misunderstanding something here... 显然我在这里误会了一些东西...

You can try initializing definitions as an object instead of array ie. 您可以尝试将定义初始化为对象,而不是数组。 var definitions = {} and the ids its properties. var definitions = {}及其ids属性。 So that you can easily loop through it with a for..in loop. 这样您就可以轻松地通过for..in循环遍历它。

As the AJAX call is async the log might run on the empty array definitions . 由于AJAX调用是异步的,因此日志可能会在空数组definitions上运行。

for (id in definitions) {
// Logic
}
var len = Object.keys(definitions).length

Try this. 尝试这个。 Not work in IE. 在IE中不起作用。 For crossbrowsers support use regular for loop. 对于跨浏览器的支持,请使用常规的for循环。

for (var object of response) {
    console.log(object.id);
    console.log(object.name);
}

Regular for 定期

var len = response.length;

for ( var i = 0; i < len; i++ ) {
    var currentObject = response[i];

    console.log(currentObject.id);
    console.log(currentObject.name);
}

In this way you get properties and then can use they as key for looping over another array/object. 通过这种方式,您可以获得属性,然后可以将其用作遍历另一个数组/对象的键。

OK, this is on me and a misunderstanding of Ajax and asynchronious request. 好的,这是我的事,并且是对Ajax和异步请求的误解。 The comments on my question helped to see the problem. 关于我的问题的评论有助于发现问题。

As stated above, I am calling this script from another server ( http://tableau.github.io/webdataconnector/Simulator/ ). 如上所述,我正在从另一台服务器( http://tableau.github.io/webdataconnector/Simulator/ )调用此脚本。 The script itself sends a request to a third server. 脚本本身将请求发送到第三台服务器。

Forcing the ajax-function to work synchroniously works: 强制ajax函数同步工作:

    $.ajax({
        url: apiUrl,
        type: 'GET',
        crossDomain: true,
        cache: false,
        async: false,

        ...})

Now the console show the array as actually filled: 现在,控制台将数组显示为实际已填充:

(790) [empty × 123, "Name1", empty × 123, "Name2", empty × 333, "Name3"]
123: "Name1"
456: "Name2"
789: "Name3"
length: 929
__proto__: Array(0)

So finally, it's not about referencing the array / object the wrong way, it's about the asynchronious call. 所以最后,不是错误地引用数组/对象,而是异步调用。

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

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