Захват результата HTML5 FileReader при использовании обещаний в асинхронном режиме - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть приложение Angular 4, где я читаю изображение и пытаюсь передать строку base64 в другую переменную - однако у меня возникла проблема из-за асинхронной природы этого - image.src пусто и, следовательно, значение правильно передал объект изображения?

ngAfterViewInit(): void {
    let image = new Image();
    var promise = this.getBase64(fileObject, this.processImage());
    promise.then(function(base64) {
        console.log(base64);    // outputs string e.g 'data:image/jpeg;base64,........'
    });

    image.src = base64; // how to get base64 string into image.src var here??

    let editor = new PhotoEditorSDK.UI.ReactUI({
        container: this.editor.nativeElement
        editor: {
           image: image
        }
    });
}

/**
 * get base64 string from supplied file object
 */
public getBase64(file, onLoadCallback) {
    return new Promise(function(resolve, reject) {
        var reader = new FileReader();
        reader.onload = function() { resolve(reader.result); };
        reader.onerror = reject;
        reader.readAsDataURL(file);
    });
}

public processImage() {

}

Ответы [ 3 ]

0 голосов
/ 17 ноября 2018

Поскольку код асинхронный по своей природе, вам придется ждать результата, если вы хотите его использовать. В вашем случае вам придется дождаться, пока ваше обещание будет выполнено . Итак, ваш код должен выглядеть так:

ngAfterViewInit(): void {
   let image = new Image();
   var promise = this.getBase64(this.fileObject, this.processImage);
   promise.then(function(base64: string) {
       console.log(base64);    
       image.src = base64;

       let editor = new PhotoEditorSDK.UI.ReactUI({
           container: this.editor.nativeElement
           editor: {
             image: image
           }
       });
   });
}

Я изменил следующие вещи:

  1. Я переместил код для ReactUI создания экземпляра внутри обратного вызова обещания
  2. Указан тип параметра base64 как string
  3. Исправлена ​​опечатка в вызове функции getBase64, от this.processImage() до this.processImage, поэтому она передает функцию обратного вызова, а не результат функции processImage.

Надеюсь, это поможет!

0 голосов
/ 18 ноября 2018

Поскольку getBase64 является асинхронной операцией, вы не можете сразу использовать ее результат. Вам нужно подождать, либо позвонив по номеру then (как вы уже экспериментировали), либо используя async/await.

Версия async/await (которая также является частью стандарта es 2017) проще понять, особенно если вы новичок в асинхронном программировании. Общее практическое правило, если вы видите Promise и вам нужно использовать значение, вам нужно будет использовать оператор await (и сделать ваш метод асинхронным)

async ngAfterViewInit() {
    let image = new Image();
    var base64 = await this.getBase64(fileObject, this.processImage());

    image.src = base64; //Now available

    let editor = new PhotoEditorSDK.UI.ReactUI({
        container: this.editor.nativeElement
        editor: {
           image: image
        }
    });
}
public getBase64(file, onLoadCallback) {
    return new Promise<string>(function(resolve, reject) {
        var reader = new FileReader();
        reader.onload = function() { resolve(reader.result as string); };
        reader.onerror = reject;
        reader.readAsDataURL(file);
    });
}

Вы также можете переместить свой код в обратный вызов, переданный вызову then, но это может быть немного сложнее для чтения (особенно, если вы только начинаете с асинхронного кода) и если вам нужно организовать несколько асинхронных операций чтение кода быстро становится проблемой

async ngAfterViewInit() {
    let image = new Image();
    this.getBase64(fileObject, this.processImage())
        .then(base64=>
        {
            image.src = base64; // available now 

            let editor = new PhotoEditorSDK.UI.ReactUI({
                container: this.editor.nativeElement
                editor: { image }
            });
        });
}
0 голосов
/ 16 ноября 2018

promise.then - это асинхронная функция, которая означает, что код приходит после того, как этот оператор будет выполнен первым, а затем будет выполнена функция обратного вызова в then. Таким образом, вы должны переместить свой код в обратный вызов then.

promise.then((base64: string) => {
    console.log(base64);    // outputs string e.g 'data:image/jpeg;base64,........'
    console.log(typeof base64); // type is string
    image.src = base64;

    let editor = new PhotoEditorSDK.UI.ReactUI({
        container: this.editor.nativeElement
        editor: {
           image: image
        }
    });
});

Редактировать: Я изменил функцию обратного вызова на функцию жирной стрелки () => {}, это потому, что вы получаете доступ к одному из полей компонента с помощью this.editor, а function имеют свою собственную область. Вы можете получить сообщение об ошибке cannot read nativeElement of undefined.

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