возвращать objectArray после forEach fini sh es6 + angular - PullRequest
0 голосов
/ 12 марта 2020

У меня есть требование, в котором мне нужно вызвать api rest со ссылками на видео типа 'https://videoapi.com/api/video.mp4', а затем создать миниатюру для каждого видеообъекта, большую часть работы я проделал, но У меня возникают проблемы, когда я пытаюсь вернуть новый массив объектов с миниатюрой, которую я создал ранее, процесс выглядит так:

  1. Извлечение данных объекта массива API

  2. для каждого элемента в объекте массива создайте миниатюру с помощью функции createThumbnail (), которая у меня есть, эта функция возвращает строку base64 url.

  3. в l oop Я создаю новый объект, используя объекты api и новый вызов propious videoThumbnail, нажимая на строку base64, которую я получаю из вышеуказанной функции.
  4. Мне нужно набрать sh каждого нового объекта, у которого есть URL-адрес миниатюры в новом объекте массива, и вернуть, когда он завершится sh.
  5. , использовать новый объект массива для чего угодно.

я делаю хорошо до части 4, я могу создать и заполнить новый объект, но я не знаю, как заставить функцию ждать до l oop fini sh, и если я пытаюсь вернуть новый объект, я получаю пустой массив.

loadThumbnail(list: any){
  let objArrayTemp = [];
  let objTemp = {};
  list.forEach((element,i) => {
  // here i'm creating the base64 strings
  this.createThumbnail(element.videoSrc).then(dataUrl => {
  // here i'm creating the new object for every element in the list
      objTemp = { ...element, videoThumbnail: dataUrl};
      // i want to push every element here
       objArrayTemp.push(objTemp)
     });
  });
 //i want to return the object when the loop finishes the populating process
  return objArrayTemp;
}
console.log(this.loadThumbnail(list)) // this return --- > []

это моя функция createThumbnail ()

async createThumbnail(thumbnail): Promise<any> {
  return new Promise(resolve => {
    let src = thumbnail; 
    let video = document.createElement('video');

    video.src = src;

    video.width = 360;
    video.height = 240;

    let canvas = document.createElement('canvas');
    canvas.width = 360; 
    canvas.height = 240;
    let context = canvas.getContext('2d');

    video.addEventListener('loadeddata', function() {
      context.drawImage(video, 0, 0, canvas.width, canvas.height);
      let dataURI = canvas.toDataURL('image/jpeg');
     resolve(dataURI)
    });
 })
}

это стек с полным воссозданным кодом: https://stackblitz.com/edit/angular-hhquzg.

спасибо за помощь.

1 Ответ

1 голос
/ 12 марта 2020

измените loadThumbnail следующим образом

loadThumbnail(list: any) {
    let objArrayTemp = [];
    let objTemp = {};
    return Promise.all(list.map((element, i) =>  
        this.createThumbnail(element.videoSrc)
        .then(dataUrl => ({...element, videoThumbnail: dataUrl}))
    ));
}

Примечание: loadThumbnails обязательно возвращает Promise, потому что асинхронность

Таким образом, чтобы "использовать" его, это что-то вроде:

this.loadThumbnail(list).then(console.log)

Кроме того, вы можете удалить async in

async createThumbnail(thumbnail): Promise<any> {

, поскольку вы никогда не используете await, и вернуть Promise в любом случае

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...