Use SerializeJSON to return an array of structs instead of JSON object with COLUMNS and DATA nodes?

不想你离开。 提交于 2020-01-02 10:28:10

问题


I am building a Railo app which deals with a lot of JSON data sent back and forth via Ajax. I've identified an opportunity to optimize its performance, but I'd like to hear some advice from the community before I tackle it.

Here is a good example of the situation.

I have an action on the server that queries a set of bid responses, serializes them to JSON, then returns them to my javascript on the front end, which then parses and renders some HTML. The format in which Railo returns the JSON is the familiar two-node object:

{"COLUMNS":["one","two","three",...],"DATA":["value","value","value",...]}

I wrote a function that utilizes underscore's map() function to convert this format into an array of objects with named nodes:

function toArgsObject(data,columns) {
return _.map(data, function(w){
    var q = {};
    for (var i=0; i < w.length; i++) { eval("q."+columns[i]+" = w[i]"); };
    return q;
});
};

This gets the job done nicely, however the performance isn't very good! Even with swift js interpreters like those in webkit and firefox, this function often accounts for 75% of processing time in the functions that call it, especially when the data sets are large. I'd like to see how much improvement I would get by offloading this processing to the server, but I don't quite have the cfml / cfscript chops to write an efficient version of this.

What I need to come back from the server, then, would look like this:

[
{"one":"value","two":"value","three":"value"},
{"one":"value","two":"value","three":"value"}.
...
]

I understand that the format used by SerializeJSON creates responses that are far smaller and therefore use less bandwidth to send. This is where the experimentation comes in. I'd like to see how it impacts my application to do things differently!

has anyone written a JSON Serializer that can return data in this format?


回答1:


eval should only be used in a few very rare cases and this certainly isn't one of them. Stop using eval and do this instead:

q[columns[i]] = w[i];

In JavaScript, foo['bar'] is the equivalent of foo.bar.




回答2:


If you need an array of structures in JS, you can easily convert the query into this type of dataset on the server-side and apply the SerializeJSON().

Quick example 1

<cfset dataset = [
    {"one":"value","two":"value","three":"value"},
    {"one":"value","two":"value","three":"value"}
] />

<cfoutput><p>#SerializeJSON(dataset)#</p></cfoutput>

(I love the freedom of structure definition syntax in Railo)

Quick example 2

<cfquery datasource="xxx" name="qGetRecords">
    select userId, login, email from users limit 0,3
</cfquery>

<cfset dataset = [] />

<cfloop query="qGetRecords">
    <cfset record = {} />
    <cfset record["one"] = qGetRecords.userId />
    <cfset record["two"] = qGetRecords.login />
    <cfset record["three"] = qGetRecords.email />
    <cfset ArrayAppend(dataset, record) />
</cfloop>

<cfoutput>
    <p>#SerializeJSON(qGetRecords)#</p>
    <p>#SerializeJSON(dataset)#</p>
</cfoutput>

Should work for you.




回答3:


In Coldfusion 10 or Railo 4, you could use the toArray() function of the Underscore.cfc library to convert your query into the format you want before calling serializeJSON(). Example in cfscript:

exampleQuery = queryNew("one,two,three","Varchar,Varchar,Varchar",
[
    ["value","value","value"],
    ["value","value","value"]
]);

arrayOfStructs = _.toArray(exampleQuery);

serializeJSON(arrayOfStructs);

Result:

[{ONE:"value", TWO:"value", THREE:"value"}, {ONE:"value", TWO:"value", THREE:"value"}]

The toArray() function returns an array of structs that matches your query, which is why the resulting JSON is formatted in the way that you want.

[Disclaimer: I wrote Underscore.cfc]



来源:https://stackoverflow.com/questions/3349107/use-serializejson-to-return-an-array-of-structs-instead-of-json-object-with-colu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!