Как использовать обещания с рекурсивной выборкой?

Я столкнулся с проблемой сортировки массива объектов с изменением приоритета значений, в основном я хочу сортировать массив людей по их возрасту, а затем по фамилии - или просто по фамилии, имени. Я думаю, что это самое простое решение по сравнению с другими ответами.

it 'используется при вызове sortPeoples ([' array ',' of ',' properties '], reverse = false)

///////////////////////example array of peoples ///////////////////////

var peoples = [
    {name: "Zach", surname: "Emergency", age: 1},
    {name: "Nancy", surname: "Nurse", age: 1},
    {name: "Ethel", surname: "Emergency", age: 1},
    {name: "Nina", surname: "Nurse", age: 42},
    {name: "Anthony", surname: "Emergency", age: 42},
    {name: "Nina", surname: "Nurse", age: 32},
    {name: "Ed", surname: "Emergency", age: 28},
    {name: "Peter", surname: "Physician", age: 58},
    {name: "Al", surname: "Emergency", age: 58},
    {name: "Ruth", surname: "Registration", age: 62},
    {name: "Ed", surname: "Emergency", age: 38},
    {name: "Tammy", surname: "Triage", age: 29},
    {name: "Alan", surname: "Emergency", age: 60},
    {name: "Nina", surname: "Nurse", age: 58}
];



//////////////////////// Sorting function /////////////////////
function sortPeoples(propertyArr, reverse) {
        function compare(a,b) {
            var i=0;
            while (propertyArr[i]) {
                if (a[propertyArr[i]] < b[propertyArr[i]])  return -1;
                if (a[propertyArr[i]] > b[propertyArr[i]])  return 1;
                i++;
            }
            return 0;
            }
        peoples.sort(compare);
        if (reverse){
            peoples.reverse();
        }
    };

////////////////end of sorting method///////////////
function printPeoples(){
  $('#output').html('');
peoples.forEach( function(person){
 $('#output').append(person.surname+" "+person.name+" "+person.age+"<br>");
} )
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
  <html>
  <body>
<button onclick="sortPeoples(['surname']); printPeoples()">sort by ONLY by surname ASC results in mess with same name cases</button><br>
<button onclick="sortPeoples(['surname', 'name'], true); printPeoples()">sort by surname then name DESC</button><br>
<button onclick="sortPeoples(['age']); printPeoples()">sort by AGE ASC. Same issue as in first case</button><br>
<button onclick="sortPeoples(['age', 'surname']); printPeoples()">sort by AGE and Surname ASC. Adding second field fixed it.</button><br>
        
    <div id="output"></div>
    </body>
  </html>

1
задан Christophe 13 July 2018 в 20:53
поделиться

2 ответа

Вот способ сделать это с помощью рекурсивной асинхронной функции, ожидающей завершения выборки дочерних элементов, прежде чем возвращать обещание.

Таким образом, мы можем вызвать doSomething, когда все будет сделано.

const tree = {
  url: 'http://www.json-generator.com/api/json/get/cevhxOsZnS',
  children: [{
    url: 'http://www.json-generator.com/api/json/get/cguaPsRxAi'
  }, {
    url: 'http://www.json-generator.com/api/json/get/cguaPsRxAi',
    children: [{
      url: 'http://www.json-generator.com/api/json/get/cfDZdmxnDm'
    }]
  }]
};

function doSomething() {
  console.log("doing something");
}

async function fetchIt(element) {
  if (element.children) {
    await Promise.all(element.children.map(fetchIt));
  }
  return new Promise((resolve) => {
    console.log("fetching " + element.url);
    fetch(element.url).then(res => {
      console.log("done");
      resolve();
    });
  });
}

fetchIt(tree).then(doSomething);

1
ответ дан Guillaume Georges 17 August 2018 в 12:10
поделиться
  • 1
    Это слишком много. – Jonas Wilms 13 July 2018 в 20:22
  • 2
    @ Кристофе Я признаю, что метод генератора был довольно сложным и в любом случае не предполагал рекурсивной выборки. Я отредактировал свой ответ. – Guillaume Georges 13 July 2018 в 21:31

Просто сначала подождите, пока элементы слоя будут извлечены, а затем рекурсивно продолжите работу с дочерними элементами и ждите, что:

async function fetchChildren(layer) {
  await Promise.all(layer.map(fetch));
  await Promise.all(layer.map(el => fetchChildren(el.children)));
}

( fetch (el) должна быть многообещающей функцией )

2
ответ дан Jonas Wilms 17 August 2018 в 12:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: