Рекурсивное обещание NodeJS не заканчивается - PullRequest
2 голосов
/ 09 апреля 2020

Я написал следующую функцию для перестройки JSON объекта, который включает рекурсивно. Но при выполнении ничего не возвращается при выполнении и console.log снова и снова регистрирует один и тот же компонент без завершения. Может ли кто-нибудь помочь мне определить проблему?

this.findOne = (id) => {
  return new Promise(resolve => {
    componentCollection.find(id).then(components => {
      if (components[0]) {
        let subComponents = components[0].components;
        for (let i = 0; i < subComponents.length; i++) {
          console.log(subComponents[i])
          subComponents[i] = resolve(this.findOne(subComponents[i].id))
        }
        components[0].components = subComponents;
      }
      resolve(components[0])
    })
  })
}

РЕДАКТИРОВАТЬ: Компоненты включают только содержит идентификатор в качестве атрибута. Вот почему я должен построить это рекурсивно, как это. Я попробовал это по-другому, и он закончился тем же бесконечным журналом:

this.findOne = async (id) => {
  let components = await componentCollection.find(id)
  if (components[0]) {
    let subComponents = components[0].components;
    for (let i = 0; i < subComponents.length; i++) {
      console.log(subComponents[i])
      subComponents[i] = await this.findOne(subComponents[i].id)
    }
    components[0].components = subComponents;
  }
  return components[0]
}

Обе попытки снова и снова регистрируют первого потомка родительского компонента.

объект, который я пытаюсь построить:

{
  id:1,
  name:"comp1",
  components:[
    {
      id:2,
      name:"comp2",
      components:[
        {
          id:3,
          name:"comp3"
        },
        {
          id:4,
          name:"comp4"
        }
      ]
    }
  ]
}

Бесконечный журнал консоли от console.log(subComponents[i]):

{
  id:2,
  name:"comp2",components:[..]
}

РЕДАКТИРОВАНИЕ:

Окружающий код findOne:

this.findone = () =>{}
module.exports = {
  findOne: this.findOne
};

Я называю это в контроллере как:

const ComponentService = require('./cs');
const component = await ComponentService.findOne(id)//id={1,2,...}

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Вот версия с использованием Promises. Предположительно было бы достаточно легко преобразовать это в async-await. Он использует чистую функцию, а не метод вашего объекта. Это не должно быть слишком сложно изменить; Я не пробовал, но, возможно, вам придется хранить локальную ссылку на this, чтобы это работало.

const findOne = (id) => new Promise (
  (resolve, reject) => 
    componentCollection .find (id) .then (
      ({components = [], ...rest}) => 
        Promise .all (components .map (({id}) => findOne (id))) .then (
          children => resolve ({...rest, components: children}), 
          reject
        ),
      reject
    )
)

findOne (5) .then (console .log, console .warn)

findOne (1) .then (console .log, console .warn)
.as-console-wrapper {min-height: 100% !important; top: 0}
<script>
// Dummy code just for demonstration
const componentCollection = {
  find: (n) => [1, 2, 3, 4] .includes (n) 
    ? Promise .resolve (
      n == 1
        ? {id: 1, name: 'comp1', components: [{id: 2}]}
      : n == 2
        ? {id: 2, name: 'comp2', components: [{id: 3}, {id: 4}]}
      : n == 3
        ? {id: 3, name: 'comp3'}
      : {id: 4, name: 'comp4'}
    ) 
    : Promise .reject (`Not found: ${n}`)
}  
</script>

Главное здесь - использовать Promise.all для преобразования списка обещаний для подкомпонентов в одно обещание, которое затем вы можете прикрепить к.

1 голос
/ 09 апреля 2020

Привет, я попробовал этот подход, когда вы пытаетесь повторить его, просто сначала сделайте объект в массиве. код: -

async function print(obj)  {
  // passing your obj in array and then iterating
  let components = [obj]
  if (components[0]) {
    let subComponents = components[0].components;
    for (let i = 0; i < subComponents.length; i++) {
      console.log(subComponents[i])
      subComponents[i] = await print(subComponents[i])
    }
    components[0].components = subComponents;
  }
  return components[0]
}
print(obj)

и вывод, который я получаю:

output i am getting

не знаю, правильно ли я, хотя

...