Promise в цикле при запросах из бд

123
12 ноября 2019, 01:50

Есть метод в классе, который должен достать из базы данных из одной таблицы текущее значение проектов, из другой таблицы их историю в разбивке по проектам и сформировать в один объект. Метод сейчас выглядит так:

showDepositorProjectsWithStory() { 
 
  this.showDepositorsProjects() 
    .then(projects => { 
 
      for (let i = 0; i < projects.length; i++) { 
        projects[i].story = this.showDepositorProjectStory(projects[i].id, this.id) 
          .then(story => { 
            return story; 
          }) 
      } 
 
      Promise.all(projects) 
        .then(result => { 
          console.log('TCL: Depositors -> showDepositorProjectsWithStory -> result', result) 
        }) 
    }) 
    .catch(err => { 
      console.log('TCL: Depositors -> showDepositorProjectsWithStory -> err', err) 
    }); 
}

и этот код не работает, так как в итоге в консоль выводится story: Promise { <pending> }. При этом, остальные данные записаны правильно. Как можно решить эту проблему?

Answer 1

Promise.all принимает массив Promise, а в данном случае ему передается массив результатов.

Вместо этого надо было собрать story в отдельный массив и именно его передать в Promise.all.

Кроме этого, результат Promise.all сейчас не ожидается.

Исправленный код может выглядеть так:

showDepositorProjectsWithStory() {
  this.showDepositorsProjects()
    .then(projects =>
      Promise.all(projects.map(p => this.showDepositorProjectStory(p.id, this.id)))
      .then(result => projects.forEach((p, i) => p.story = result[i])))
    .then(result => {
      console.log('TCL: Depositors -> showDepositorProjectsWithStory -> result', result)
    })
    .catch(err => {
      console.log('TCL: Depositors -> showDepositorProjectsWithStory -> err', err)
    });
}

Вариант с async/await

async showDepositorProjectsWithStory() {
  try {
    var projects = await this.showDepositorsProjects();
    var stories = await Promise.all(projects.map(p => this.showDepositorProjectStory(p.id, this.id)));
    projects.forEach((p, i) => p.story = stories[i]);
    console.log('TCL: Depositors -> showDepositorProjectsWithStory -> result', result);
  } catch(err) {
      console.log('TCL: Depositors -> showDepositorProjectsWithStory -> err', err)
  };
}
Answer 2

После ответа @Grundy сделал следующее:

showDepositorProjectsWithStory() { 
 
  this.showDepositorsProjects() 
    .then(projects => { 
 
      var storeArray = []; 
 
      for (let i = 0; i < projects.length; i++) { 
        storeArray.push(this.showDepositorProjectStory(projects[i].id, this.id)); 
      } 
 
      Promise.all(storeArray) 
        .then(result => { 
          projects.forEach((p, i) => p.story = result[i]); 
        }) 
    }) 
    .catch(err => { 
      console.log('TCL: Depositors -> showDepositorProjectsWithStory -> err', err) 
    }); 
 
}

По ощущениям у него лаконичнее и короче код.

Answer 3
function showDepositorProjectsWithStory() {
    this.showDepositorsProjects().then(projects => {

  }
  /// Вызов 
  showDepositorProjectsWithStory().then(data => {
      data;
  })
Answer 4

Альтернативный вариант с использованием async\await.

showDepositorProjectsWithStory() { 
 
  this.showDepositorsProjects() 
    .then(async projects => { 
 
      for (let i = 0; i < projects.length; i++) { 
        projects[i].story = await this.showDepositorProjectStory(projects[i].id, this.id); 
      } 
      console.log('TCL: Depositors -> showDepositorProjectsWithStory -> result', projects) 
    }) 
    .catch(err => { 
      console.log('TCL: Depositors -> showDepositorProjectsWithStory -> err', err) 
    }); 
}

READ ALSO
Регулярное выражение - цифры и дефис [закрыт]

Регулярное выражение - цифры и дефис [закрыт]

Подскажите регулярку такого вида:

118
Как сравнить два списка javascript?

Как сравнить два списка javascript?

Как сравнить два списка? И вывести отсутствующий элемент?

79
Instagram API. Почему постоянно выдает ошибку токена?

Instagram API. Почему постоянно выдает ошибку токена?

Использую для галереи на сайте instafeedjs

89
vue js базовая часть

vue js базовая часть

не понимаю что не так вроде базовая вещь ошибки

123