简体   繁体   English

如何按 javascript 中的键值对 object 进行排序?

[英]How to sort object by key value in javascript?

I'm making a code to fetch content from contentful using AJAX.我正在编写代码以使用 AJAX 从内容中获取内容。 I've success retrieve data and display it, but something is not quite what I want.我已经成功检索数据并显示它,但有些东西不是我想要的。 Because the content that I get is not in the same order as the contentful cms, so I add another field called sequence .因为我得到的内容和内容丰富的 cms 的顺序不同,所以我添加了另一个名为sequence的字段。 So in my code I added a sort() and Object.keys() function before forEach() , but there is no error and data not appears,does anyone know why data not appears?所以在我的代码中,我在forEach()之前添加了一个sort()Object.keys() function ,但是没有错误并且没有出现数据,有谁知道为什么没有出现数据?

If you want to try debugging, you can look at This Codepen .如果您想尝试调试,可以查看This Codepen

 function renderContentBySection(sectionName, appendElement, numberOfSkeleton, elementAttribute, elementClass){ $.ajax({ url: 'https://cdn.contentful.com/spaces/r5mgd95bqsb5/environments/master/entries/1bI13SpZBBvgOgIk4GhYEg?access_token=CVel_r57GUqeTeaLyIsseXEAM1z1f-spXNKR-a2-huA', type: 'GET', success: function(data){ const getData = data.fields if(getData[sectionName]) { if(getData[sectionName] && getData[sectionName].length) { getData[sectionName].forEach((item, index) => { getSingleEntry(item.sys.id) }); } } } }); } function getSingleEntry(contentId){ $.ajax({ url: `https://cdn.contentful.com/spaces/r5mgd95bqsb5/environments/master/entries/${contentId}?access_token=CVel_r57GUqeTeaLyIsseXEAM1z1f-spXNKR-a2-huA`, type: 'GET', success: function(dataKat){ getAssetData(dataKat.fields.image.sys.id, dataKat.fields.sequence) $('.data-banner').append(JSON.stringify(dataKat.fields, null, 4)) $('.data-banner').append('<br>'); } }); } function getAssetData(assetsId, sequenceId){ $.ajax({ url: `https://cdn.contentful.com/spaces/r5mgd95bqsb5/environments/master/assets/${assetsId}?access_token=CVel_r57GUqeTeaLyIsseXEAM1z1f-spXNKR-a2-huA`, type: 'GET', success: function(getAssetsData){ $('.data-image').append(JSON.stringify(getAssetsData.fields, null, 4)) $('.data-image').append('<br>'); } }); } $(document).ready(function(){ renderContentBySection('mainBannerImage', '#carousel-inner', 1, 'banner', 'main-banner-item'); })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <pre class="data-banner"> <h4>Get Data Main Banner:</h4> </pre> <br> <pre class="data-image"> <h4>Get Data for Each Image in Main Banner:</h4> </pre>

Because your data is loaded asyncronously, you will need to create a queue of your requests, and listen for them to all finish.因为您的数据是异步加载的,所以您需要创建一个请求队列,并等待它们全部完成。

I have commented my code below so you can understand how it works.我在下面评论了我的代码,以便您了解它是如何工作的。

First, you need to use the spread operator a lot ... , to work with an unknown number of array elements.首先,您需要大量使用扩展运算符...来处理未知数量的数组元素。 ( https://stackoverflow.com/a/35169449/1410567 ) https://stackoverflow.com/a/35169449/1410567

Second, you need to use $.when(...array).done(function(...results) { to know when the requests have finished. ( https://blog.kevinchisholm.com/javascript/jquery/using-jquery-deferred-to-manage-multiple-ajax-calls/ )其次,您需要使用$.when(...array).done(function(...results) {来了解请求何时完成。( https://blog.kevinchisholm.com/javascript/jquery/using -jquery-deferred-to-manage-multiple-ajax-calls/ )

Third, you need to use Array.sort() to sort the array of objects, comparing their sequence , and returning 1 or -1 to sort them.第三,您需要使用Array.sort()对对象数组进行排序,比较它们的sequence ,并返回 1 或 -1 对它们进行排序。 ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort ) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

 //create an empty array to hold the queue: let allImageRequests = []; function listenForImages() { //set up a listener for when all requests have finished, using "spread operator" (...) to send all requests as parameters to when(): $.when(...allImageRequests).done( //done: function (...arrAllImagesResp) { let arrAllImages = []; console.log("arrAllImagesResp", arrAllImagesResp); arrAllImagesResp.forEach((e) => { console.log(e); arrAllImages.push(e[0].fields); });; //all images loaded, sort: arrAllImages.sort((a, b) => (a.sequence < b.sequence? -1: 1)); console.log("done", arrAllImages); //sorting done, display results: $('.data-image').append("\n\n<strong>All Images Sorted:</strong> \n\n" + JSON.stringify(arrAllImages, null, 4)); } ); } $.ajax({ url: 'https://cdn.contentful.com/spaces/r5mgd95bqsb5/environments/master/entries/1bI13SpZBBvgOgIk4GhYEg?access_token=CVel_r57GUqeTeaLyIsseXEAM1z1f-spXNKR-a2-huA', type: 'GET', success: function (data) { console.log("got data", data); const getData = data.fields.mainBannerImage $('.data-banner').append(JSON.stringify(getData, null, 4)) $('.data-banner').append('<br>'); getData.forEach((item, index) => { //add requests to our queue: allImageRequests.push(getImageAssets(item.sys.id)); }); listenForImages(); } }) function getImageAssets(assetId) { //I added a return here, so the XHR objects will be push()'d to the allImageRequests queue array: return $.ajax({ url: `https://cdn.contentful.com/spaces/r5mgd95bqsb5/environments/master/entries/${assetId}?access_token=CVel_r57GUqeTeaLyIsseXEAM1z1f-spXNKR-a2-huA`, type: 'GET', success: function (assetsData) { const getAssetsData = assetsData.fields $('.data-image').append(JSON.stringify(getAssetsData, null, 4)) $('.data-image').append('<br>'); } }) }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <pre class="data-banner"> <h4>Get Data Main Banner:</h4> </pre> <br> <pre class="data-image"> <h4>Get Data for Each Image in Main Banner:</h4> </pre>

Because you completely changed the criteria, I will provide an answer for your second ask.因为您完全改变了标准,所以我将为您的第二个问题提供答案。

The key to working with multiple batches of asynchronous requests is to gather all the requests, and then listen for them all to complete.处理多批异步请求的关键是收集所有请求,然后监听它们以完成。 Then, do the same thing again with the next batch of requests.然后,对下一批请求再次执行相同的操作。

Otherwise, your HTML will print in the order the responses are returned and it will seem random.否则,您的 HTML 将按照返回响应的顺序打印,并且看起来是随机的。

Once you have gathered all the completed requests, you can sort() them, then do a forEach through them.一旦你收集了所有完成的请求,你可以对它们进行sort() ,然后通过它们执行一个forEach

 function listenForEntries(arrAllEntryRequests) { //set up a listener for when all requests have finished, using "spread operator" (...) to send all requests as parameters to when(): $.when(...arrAllEntryRequests).done( //done: function (...arrAllEntryResponses) { let arrAllEntries = []; //console.log("arrAllEntryResponses", arrAllEntryResponses); arrAllEntryResponses.forEach((e) => { arrAllEntries.push(e[0].fields); });; //all images loaded, sort: arrAllEntries.sort((a, b) => (a.sequence < b.sequence? -1: 1)); //sorting done, get asset data for each. This is also asyncronous so you need to do the same thing as above: let arrAllAssetRequests = []; arrAllEntries.forEach((entryData) => { //console.log("entryData", entryData); $('.data-sequence').append(` <ul> <li> Sequence ID: ${entryData.sequence}<br> Title Banner: ${entryData.title} </li> </ul>`) let assetReqObj = getAssetData(entryData.image.sys.id, entryData.sequence); arrAllAssetRequests.push(assetReqObj); }); listenForAssets(arrAllAssetRequests); } ); } function listenForAssets(arrAllAssetRequests) { $.when(...arrAllAssetRequests).done( //done: function (...arrAllAssetResponses) { //all assets loaded, sort: arrAllAssetResponses.sort((a, b) => (a[2].sequence < b[2].sequence? -1: 1)); arrAllAssetResponses.forEach((assetData) => { //console.log("assetData", assetData); if(assetData.length > 0) { $('.data-assets').append(` <ul> <li> Sequence ID: ${assetData[2].sequence}<br> Title Banner: ${assetData[0].fields.title}<br> <img class="img-fluid" src="${assetData[0].fields.file.url}"> </li> </ul>`); } else { console.error("Something wrong with assetData", assetData); } }); } ); } function renderContentBySection(sectionName, appendElement, numberOfSkeleton, elementAttribute, elementClass) { $.ajax({ url: 'https://cdn.contentful.com/spaces/r5mgd95bqsb5/environments/master/entries/1bI13SpZBBvgOgIk4GhYEg?access_token=CVel_r57GUqeTeaLyIsseXEAM1z1f-spXNKR-a2-huA', type: 'GET', success: function (data) { const getData = data.fields //move array to inside this function as it's the only place it will be used: let arrAllEntryRequests = []; if (getData[sectionName]) { if (getData[sectionName] && getData[sectionName].length) { getData[sectionName].forEach((item, index) => { arrAllEntryRequests.push(getSingleEntry(item.sys.id)); }); //once array of requests is created, listen for it to finish: listenForEntries(arrAllEntryRequests); } } } }); } function getSingleEntry(contentId) { return $.ajax({ url: `https://cdn.contentful.com/spaces/r5mgd95bqsb5/environments/master/entries/${contentId}?access_token=CVel_r57GUqeTeaLyIsseXEAM1z1f-spXNKR-a2-huA`, type: 'GET', success: function (dataKat) { //do nothing } }); } function getAssetData(assetsId, sequenceId) { let $xhr = $.ajax({ url: `https://cdn.contentful.com/spaces/r5mgd95bqsb5/environments/master/assets/${assetsId}?access_token=CVel_r57GUqeTeaLyIsseXEAM1z1f-spXNKR-a2-huA`, type: 'GET', success: function (assetData) { //do nothing } }); $xhr.sequence = sequenceId; //store the sequence for later return $xhr; } $(document).ready(function () { renderContentBySection('mainBannerImage', '#carousel-inner', 1, 'banner', 'main-banner-item'); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container-fluid"> <div class="row"> <div class="col-6"> <div class="data-sequence"> <span> This is sequence data:</span> </div> </div> <div class="col-6"> <div class="data-assets"> <span> This is assets data:</span> </div> </div> </div> </div>

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

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