Как с помощью fetch распарсить картинку в base64 асинхронно?

есть такая функция и она работает )

  function toDataURL(url, callback) {
        var xhr = new XMLHttpRequest();
        xhr.onload = function() {
          var reader = new FileReader();
          reader.onloadend = function() {
            callback(reader.result);
          }
          reader.readAsDataURL(xhr.response);
        };
        xhr.open('GET', url);
        xhr.responseType = 'blob';
        xhr.send();
    }

но я пишу асинхронный код

let url = 'https://somethingoffreedom.com/wp-content/uploads/2019/01/Kelingking-beach-Nusa-Penida-Bali-travel-tips.jpg';


async function setBaseImg () {
  const response = await fetch(url);
  const data     = await response.blod();
  let   reader   = await new FileReader();
  
  
  await document.querySelectorAll('img')[0].setAttribute('src', reader.readAsDataURL(data) )
}


setBaseImg();
<img src="" alt="">

но он не работает , как мне его оживить что бы в src загрузилось base64 или если это не возможно то как я могу применит асинхронно функцию toDataURL ?


Ответы (2 шт):

Автор решения: WVFFLIFE

let url =
  "https://somethingoffreedom.com/wp-content/uploads/2019/01/Kelingking-beach-Nusa-Penida-Bali-travel-tips.jpg";


function setBase64ToImage(result) {
  const element = document.querySelector("img");
  element.setAttribute('src', result);
  console.log(element);
}

async function loadImg() {
  const response = await fetch(url);
  const data = await response.blob();

  let reader = new FileReader();
  reader.onloadend = function() {
    setBase64ToImage(reader.result)
  }

  reader.readAsDataURL(data);
}

loadImg();
<img src="" alt="Image"/>

→ Ссылка
Автор решения: Grundy

У FileReader если только методы с callback, поэтому часть с

let reader = await new FileReader();
...
, reader.readAsDataURL(...)

не может работать.

Для решения нужно либо оставить подход с callback какой и был:

let url = 'https://somethingoffreedom.com/wp-content/uploads/2019/01/Kelingking-beach-Nusa-Penida-Bali-travel-tips.jpg';

async function setBaseImg() {
  const response = await fetch(url);
  const data = await response.blob();

  var reader = new FileReader();
  reader.onloadend = function() {
    document.querySelectorAll('img')[0].setAttribute('src', reader.result)
  }
  reader.readAsDataURL(data);
}


setBaseImg();

Либо обернуть работу с callback в функцию возвращающую Promise

let url = 'https://somethingoffreedom.com/wp-content/uploads/2019/01/Kelingking-beach-Nusa-Penida-Bali-travel-tips.jpg';

function readAsync(data) {
    return new Promise(r=>{
        var reader = new FileReader();
        reader.onloadend = function() {
          r(reader.result)
        }
        reader.readAsDataURL(data);        
    });
}

async function setBaseImg() {
  const response = await fetch(url);
  const data = await response.blob();
  const dataUrl = await readAsync(data);

  document.querySelectorAll('img')[0].setAttribute('src', dataUrl);
}

setBaseImg();

Кроме того, НЕ НУЖНО везде добавлять await, их нужно добавлять только там, где надо.

→ Ссылка