以下名为runQuery was given to me by @Brad的javascript函数
它使用获取API从NodeJS服务器获取数据。
效果很好!它从服务器返回数据。
现在,我正在尝试对所有返回的数据进行排序。
以下代码运行无误,但返回最终的console.log命令查看时未排序的数据。
这是因为由于runQuery是异步的,所以sort函数在空数组上工作,因此不执行任何操作。然后,在runQuery有机会完成后,console.log将显示填充后的数组(未排序)。
只有将所有数据发送到浏览器后,才能帮助我理解如何对结果进行排序吗? 谢谢,约翰
P.S。此项目的所有工作代码都共享here
// Run the query defined in the textarea on the form.
runQuery(document.querySelector(".queryExpressionTextArea").value).then(function()
{
// Sort the recordsArray which was populated after running the query.
recordsArray.sort(function(a,b)
{
//Sort by email
if (a.email > b.email) return -1;
if (a.email < b.email) return 1;
if (a.email === b.email) return 0;
})
console.log(recordsArray);
});
async function runQuery(queryExpression)
{
// Define a client function that calls for data from the server.
const fetchPromise = fetch('api/aUsers' + queryExpression)
.then
(
(res) =>
{
// Verify that we have some sort of 2xx response that we can use
if (!res.ok)
{
// throw res;
console.log("Error trying to load the list of users: ");
}
// If no content,immediately resolve,don't try to parse JSON
if (res.status === 204)
{
return;
}
// Initialize variable to hold chunks of data as they come across.
let textBuffer = '';
// Process the stream.
return res.body
// Decode as UTF-8 Text
.pipeThrough
(
new TextDecoderStream()
)
// Split on lines
.pipeThrough
(
new TransformStream
(
{
transform(chunk,controller)
{
textBuffer += chunk;
// Split the string of records on the new line character and store the result in an array named lines.
const lines = textBuffer.split('\n');
// Cycle through all elements in the array except for the last one which is only holding a new line character.
for (const line of lines.slice(0,-1))
{
// Put the element from the array into the controller que.
controller.enqueue(line);
} // End of: for (const line ...)
// Put the last element from the array (the new line character) into the textBuffer but don't put it in the que.
textBuffer = lines.slice(-1)[0];
},// End of: Transform(chunk,controller){do stuff}
flush(controller)
{
if (textBuffer)
{
controller.enqueue(textBuffer);
} // End of: if (textBuffer)
} // End of: flush(controller){do stuff}
} // End of: parameters for new TransformStream
) // End of: call to constructor new TransformStream
) // End of: parameters for pipeThrough - Split on lines
// Parse JSON objects
.pipeThrough
(
new TransformStream
(
{
transform(line,controller)
{
if (line)
{
controller.enqueue
(
JSON.parse(line)
); //End of: call to controller.enqueue function
} // End of: if (line)
} // End of: transform function
} // End of: parameter object for new TransformStream
) // End of: new TransformStream parameters
); // End of: parameters for .pipeThrough - Parse JSON objects
} // End of: .then callback function instruction for fetch
); // End of: .then callback parameters for fetch
// Call to function which asks server for data.
const res = await fetchPromise;
const reader = res.getReader();
function read()
{
reader.read()
.then
(
({value,done}) =>
{
if (value)
{
// Your record object (value) will be here.
// This is a key/value pair for each field in the record.
//*************************
// This array has global scope.
// I want to sort this array only after all the data has been returned.
// In other words - only after this asynchronous function has finished running.
recordsArray.push(value);
//*************************
// If I were to uncomment the sort function in this position then
// we will see the records sorted correctly in the final console.log.
// I don't want to do this because then the sort function will
// run every time a record is returned rather than one time after
// all the records have been retrieved.
//recordsArray.sort(function(a,b)
//{
// //Sort by email
// if (a.email > b.email) return -1;
// if (a.email < b.email) return 1;
// if (a.email === b.email) return 0;
//})
} // End of: if(value){do stuff}
if (done) {return;}
read();
} // End of: the actual anonymous callback arrow function.
); // End of: .then callback after read function completes.
} // End of: function definition: function read(){do stuff}
// Call the "read" function defined above when the submit query button is pressed.
read()
}; // End of: async function runQuery(queryExpression)