Как бы я сделал сопоставленное асинхронное преобразование вложенной структуры? - PullRequest
0 голосов
/ 08 февраля 2019

Скажем, у меня есть код, который выглядит следующим образом:

const myObject = {
   outerList : [
      {
         innerList: [
            1, 2, 3
         ]
      }, 
      {
         innerList: [
            2, 4, 6
         ]
      }
   ]
}; 

async function asyncTransform(i) {  
    return new Promise((resolve) => {
      setTimeout(() => {
          resolve(i+1); 
      }, Math.random()* 1000); 
    }); 
}

async function asyncTransformNestedObject(obj) {
   //??? 
}

asyncTransformNestedObject(myObject).then((result) => {
    console.log(result);
}); 

И я хочу преобразовать объект в это:

{
   outerList : [
      {
         innerList: [
            2, 3, 4
         ]
      }, 
      {
         innerList: [
            3, 5, 7
         ]
      }
   ]
}; 

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

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

Вот решение, в котором я остановился:

Это довольно просто, когда вы об этом думаете:

Promise.all of Promise.all будет разрешен максимальновремя всех обещаний.

const myObject = {
   outerList : [
      {
         innerList: [
            1, 2, 3
         ]
      }, 
      {
         innerList: [
            2, 4, 6
         ]
      }
   ]
}; 

async function asyncTransform(i) {  
    return new Promise((resolve) => {
      setTimeout(() => {
          resolve(i+1); 
      }, Math.random()* 1000); 
    }); 
}

async function transformInnerObj(innerObj) {    
    const newInnerList = await Promise.all(innerObj.innerList.map(i => asyncTransform(i))); 
    return {
      innerList: newInnerList
    }; 
}

async function asyncTransformNestedObject(obj) {
   
   const newOuterList = await Promise.all(obj.outerList.map(innerObj =>       transformInnerObj(innerObj)));                                           
   return {
      outerList:  newOuterList                                  
   }; 
}

asyncTransformNestedObject(myObject).then(result => {
    console.log(result);
});
0 голосов
/ 08 февраля 2019

Я бы решил эту проблему, используя рекурсивную setTimeout / requestAnimationFrame в ES5, но если вы настаиваете на асинхронной функции, похоже, это поможет:

     async function convert(arr,i = 0){
            if(!arr[i]){return arr}
            await arr[i].innerList.reduce((ac,d,i,a) => ++a[i],(async function(){}()));
            return convert(arr,++i);
        }

    convert(myObject.outerList);

//myObject
    "[
        {
            "innerList": [
                2,
                3,
                4
            ]
        },
        {
            "innerList": [
                3,
                5,
                7
            ]
        }
    ]"

Вы ничего не указали о мутировании оригиналаобъект, поэтому я изменил его на месте.Я также возвратил innerArray, вы могли бы вернуть сам объект и использовать await для хранения в переменной.

0 голосов
/ 08 февраля 2019
  • Array.map каждый внутренний элемент в Promise, возвращаемый asyncTransform, а затем передать этот массив в Promise.all .
  • Затем Promise.all каждый Promise.all создан на шаге 1.

Вот пример:

const myObject = {
  outerList : [
    {
      innerList: [
        1, 2, 3
      ]
    }, 
    {
      innerList: [
        2, 4, 6
      ]
    }
  ]
}

function asyncTransform(i) {
  return new Promise(resolve => setTimeout(() => resolve(i + 1), 50))
}

function asyncTransformNestedObject(obj) {    
  const innerLists = obj.outerList.map(el => {
    return Promise.all(el.innerList.map(asyncTransform))
      .then(results => el.innerList = results)
  })
  
  return Promise.all(innerLists)
    .then((results, i) => obj.outerList.map((el, i) => ({ 
        ...el, 
        innerList: results[i] 
      })))
}


asyncTransformNestedObject(myObject).then((result) => {
  console.log(result)
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...