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

Capture result of HTML5 FileReader when using promises in async

我有一个 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() {

}

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

由于代码本质上是异步的,所以要使用的话需要等待结果。在你的情况下,你将不得不等到你的承诺得到解决。所以你的代码应该是这样的:

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

希望对您有所帮助!

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