Javascript - ожидание окончания заполнения массива - PullRequest
0 голосов
/ 04 июня 2018

Я пытаюсь получить значение некоторых элементов массива.Он работает для элементов [0], [1], [2], [3], но не для [4].

function getBase64() {
  const urls = ['https://i.imgur.com/egNg7JU.jpg',
    'https://i.imgur.com/RLZ7WH1.jpg', 'https://i.imgur.com/qfabBbA.jpg',
    'https://i.imgur.com/Zuh1KaX.jpg', 'https://i.imgur.com/yD7X6Q1.jpg'
  ];

  let base64urls = [];

  const start = async () => {
    await asyncForEach(urls, async (num) => {
      await waitFor(50)
      toDataURL(num, function(dataURL) {
        base64urls.push(dataURL);
      });
    })
    console.log(base64urls);
    console.log(base64urls[4]);
  }
  start()

}

async function asyncForEach(array, callback) {
  for (let index = 0; index < array.length; index++) {
    await callback(array[index], index, array)
  }
}

const waitFor = (ms) => new Promise(r => setTimeout(r, ms))

toDataURL просто возвращает значение base64 изображения.Всякий раз, когда я пытаюсь console.log(base64urls[4]), он возвращает «неопределенное».Я получаю правильное значение для предыдущих элементов.Есть ли способ реструктурировать это или использовать другой метод ожидания полного заполнения массива перед проверкой значений его элементов?

EDIT

Вот мой toDataURL

function toDataURL(src, callback) {
  const image = new Image();
  image.crossOrigin = 'Anonymous';

  image.onload = function () {
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    canvas.height = this.naturalHeight;
    canvas.width = this.naturalWidth;
    context.drawImage(this, 0, 0);
    const dataURL = canvas.toDataURL('image/jpeg');
    callback(dataURL);
  };

  image.src = src;
}

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Вы можете использовать promise.all для такой ситуации, чтобы дождаться результатов ваших запросов

const urls = ['https://i.imgur.com/egNg7JU.jpg', 
'https://i.imgur.com/RLZ7WH1.jpg', 'https://i.imgur.com/qfabBbA.jpg', 
'https://i.imgur.com/Zuh1KaX.jpg', 'https://i.imgur.com/yD7X6Q1.jpg'];

let base64urls = [];
 
Promise.all(urls.map(url => fetch(url))).then(res => toBase64DataURL(res)).then(result => {base64urls.push(result.toDataURL());
console.log(base64urls);});

function toBase64DataURL(src) {
  return new Promise(resolve => {
const image = new Image();
image.crossOrigin = 'Anonymous';

image.onload =  _=> {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  canvas.height = this.naturalHeight;
  canvas.width = this.naturalWidth;
  context.drawImage(this, 0, 0);
  const dataURL = canvas.toDataURL('image/jpeg');
  resolve(dataURL);
};
image.src = src;
  });
}
  
0 голосов
/ 04 июня 2018

Похоже, toDataURL является асинхронным и основан на обратном вызове - либо измените его так, чтобы он возвращал Promise и await, что Promise, либо передайте Promise resolve в обратный вызов:

async function getBase64() {
  const urls = ['https://i.imgur.com/egNg7JU.jpg', 
                'https://i.imgur.com/RLZ7WH1.jpg', 'https://i.imgur.com/qfabBbA.jpg', 
                'https://i.imgur.com/Zuh1KaX.jpg', 'https://i.imgur.com/yD7X6Q1.jpg'];
  const base64urls = [];
  for (const url of urls) {
    const dataURL = await new Promise(resolve => toDataURL(url, resolve));
    base64urls.push(dataURL);
  }
  console.log(base64urls);
  console.log(base64urls[4]);
}

Если вы хотите изменить функцию toDataURL, чтобы она возвращала Promise, чтобы вам не приходилось рассматривать ее как обратный вызов:

function toDataURL(src) {
  return new Promise(resolve => {
    const image = new Image();
    image.crossOrigin = 'Anonymous';

    image.onload = function () {
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      canvas.height = this.naturalHeight;
      canvas.width = this.naturalWidth;
      context.drawImage(this, 0, 0);
      const dataURL = canvas.toDataURL('image/jpeg');
      resolve(dataURL);
    };
    image.src = src;
  });
}

, а затем const dataURL = await toDataURL(url)

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