Javascript-等待数组完成填充

Javascript-等待数组完成填充,javascript,arrays,asynchronous,Javascript,Arrays,Asynchronous,我试图得到一些数组元素的值。它适用于元素[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

我试图得到一些数组元素的值。它适用于元素[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
是异步的,并且是基于回调的-要么更改它,使其返回
Promise
wait
Promise
,要么将
Promise
解析
传递到回调中:

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]);
}
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;
  });
}
如果要将
toDataURL
函数更改为返回承诺,以便不必将其视为回调:

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]);
}
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=wait-toDataURL(url)

在这种情况下,您可以使用它来等待查询结果

constURL=['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'];
让base64url=[];
Promise.all(url.map(url=>fetch(url)))。然后(res=>toBase64DataURL(res))。然后(result=>{base64url.push(result.toDataURL());
log(base64url);});
函数toBase64DataURL(src){
返回新承诺(解决=>{
常量图像=新图像();
image.crossOrigin='匿名';
image.onload=\u=>{
const canvas=document.createElement('canvas');
const context=canvas.getContext('2d');
canvas.height=this.naturalHeight;
canvas.width=this.naturalWidth;
drawImage(this,0,0);
const dataURL=canvas.toDataURL('image/jpeg');
解析(dataURL);
};
image.src=src;
});
}

可能重复的
等待等待(50)
为什么会出现小停顿?听起来您并不是在等待异步操作完成,而是交叉手指,希望您已经等待了很长时间。对不起,我到底应该在我的
toDataURL
中更改什么?我已经将它添加到我的问题中。我发布的代码片段将一个
承诺
解析
传递到基于回调的
toDataURL
,允许它被
等待
,因此您不需要用此更改
toDataURL
。我尝试了第一种方法,但现在整个数组是空的:/