使用Javascript Fetch API对异步获取的数据进行排序 [英] Sorting Data Fetched Asynchronously with Javascript Fetch API

查看:67
本文介绍了使用Javascript Fetch API对异步获取的数据进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@Brad提供了以下名为runQuery 的JavaScript函数
它使用获取API从NodeJS服务器获取数据.
效果很好!它从服务器返回数据.

The following javascript function called runQuery was given to me by @Brad
It gets data from a NodeJS server using the fetch API.
It works great! It returns data from the server.

现在,我正在尝试对所有返回的数据进行排序.
以下代码运行无错误,但使用最终的console.log命令查看时,返回未排序的数据.
那是因为由于runQuery是异步的,所以sort函数正在空数组上工作,因此它什么也不做.然后,在runQuery有机会完成后,console.log会显示填充后的数组(未排序).

Now I am trying to sort the data after all of it has been returned.
The following code runs without error but returns the data unsorted when viewed with the final console.log command.
That's because since runQuery is asynchronous, the sort function is working on an empty array so it does nothing. Then later, the console.log is showing the populated array (unsorted) after runQuery has had a chance to do it's work.

只有将所有数据发送到浏览器后,才能帮助我理解如何对结果进行排序吗? 谢谢,约翰

Can someone please help me understand how to sort the results only after all the data has been sent to the browser? Thanks, John

P.S. 此处

// 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)

推荐答案

好像没有在寻找任何流媒体.只需写

Looks like you're not looking for any streaming. Just write

async function runQuery(queryExpression) {
    const res = await fetch('api/aUsers' + queryExpression);
    // Verify that we have some sort of 2xx response that we can use
    if (!res.ok) {
        console.log("Error trying to load the list of users: ");
        throw res;
    }
    // If no content, immediately resolve, don't try to parse JSON
    if (res.status === 204) {
        return [];
    }
    const content = await res.text();
    const lines = content.split("\n");
    return lines.map(line => JSON.parse(line));
}

然后

const recordsArray = await runQuery(document.querySelector(".queryExpressionTextArea").value);
recordsArray.sort(function(a, b) {
    return (a.email < b.email) - (a.email > b.email);
})
console.log(recordsArray); 

这篇关于使用Javascript Fetch API对异步获取的数据进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆