在异步中使用Promise时捕获HTML5 FileReader的结果

时间:2018-11-08 15:35:28

标签: angular html5 typescript es6-promise photoeditorsdk

我有一个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 :(得分:6)

由于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 }
            });
        });
}

答案 1 :(得分:3)

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.editorfunction访问组件字段之一有自己的范围。您可能会收到一个错误消息,说cannot read nativeElement of undefined

答案 2 :(得分:3)

由于代码本质上是异步,因此,如果要使用它,则必须等待结果。就您而言,您将必须等待您的承诺得到解决。因此您的代码应如下所示:

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实例化的代码在promise回调中
  2. base64参数的指定类型为string
  3. 修复了getBase64函数调用中的错字,从this.processImage()this.processImage,因此它传递的是回调函数,而不是processImage函数的结果。

我希望这会有所帮助!