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

Zab*_*abs 6 html5 typescript es6-promise angular 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() {

}
Run Code Online (Sandbox Code Playgroud)

Tit*_*mir 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);
    });
}
Run Code Online (Sandbox Code Playgroud)

您还可以将代码移动到传递给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 }
            });
        });
}
Run Code Online (Sandbox Code Playgroud)


Dip*_*hah 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
           }
       });
   });
}
Run Code Online (Sandbox Code Playgroud)

我改变了以下事情:

  1. ReactUI在承诺回调中移动了实例化代码
  2. 指定参数类型base64string
  3. getBase64修复了函数调用中的拼写错误,从this.processImage()this.processImage因此它传递的是回调函数而不是processImage函数的结果。

我希望这有帮助!