Как вызывать функции только после завершения предыдущего - PullRequest
0 голосов
/ 01 июля 2019

Я застрял в попытке получить imageData изображения base64.У меня есть 2 функции, и проблема в том, что вторая функция запускается раньше, чем заканчивается первая.

У меня есть 2 функции

frame.restoreImageDataForLayers();
frame.changeResultLayer();

первая - загрузить изображение на страницу, а затем изменить переменные 'слои.data 'to imageData этого загруженного изображения.второй - работа с imageData изображения.

restoreImageDataForLayers() {
    this.layers.forEach((item) => {
      const layer = item;
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      const image = new Image();
      image.onload = function drawImg() {
        context.drawImage(image, 0, 0);
        layer.data = context.getImageData(0, 0, layer.canvasSize, layer.canvasSize).data;
console.log('FIRST', layers.data');
      };
      image.src = layer.data;

    });
  }

changeResultLayer() {
    console.log('SECOND', this.layers[0].data);
  }

А потом у меня второй консольный журнал перед первым консольным журналом и мой другой код, который должен работать с imageData - сбой.Как это исправить?

1 Ответ

0 голосов
/ 01 июля 2019

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

restoreImageDataForLayers() {
  const layerPromises = this.layers.map(item => {
    return new Promise((resolve, reject) => {

      // All your canvas-image code here...

      image.onload = function(){

        // Your onload code here

        // Then resolve the promise for this item
        resolve()
      }
    })
  })

  return Promise.all(layerPromises)
}

Для этого вам нужно обернуть процедуру загрузки изображения в обещание. Используйте array.map(), чтобы создать массив этих обещаний, по одному для каждого элемента. Затем используйте Promise.all(), чтобы создать одно обещание, которое разрешается только тогда, когда все обещания в массиве разрешаются.

Чтобы вызвать эту функцию, вы просто делаете это:

frame.restoreImageDataForLayers().then(() => {
  frame.changeResultLayer();
});

Или, если вызывающий абонент находится в функции async, сделайте следующее:

async thatWrapperFunction(){
  await frame.restoreImageDataForLayers();
  frame.changeResultLayer();
}
...