7

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

}
4

3 回答 3

7

由于getBase64是异步操作,因此您不能立即使用它的结果。then您需要通过调用(正如您已经尝试过的那样)或使用来等待它async/await

async/await版本(也是 es 2017 标准的一部分)更易于理解,特别是如果您不熟悉异步编程。一般的经验法则,如果您看到 aPromise并需要使用该值,您将需要使用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 }
            });
        });
}
于 2018-11-18T01:33:19.013 回答
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.editor,并且functions 有自己的范围。您可能会收到一条错误消息cannot read nativeElement of undefined

于 2018-11-16T13:07:44.220 回答
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在承诺回调中移动了用于实例化的代码
  2. 指定的base64参数类型为string
  3. 修复了getBase64函数调用中的拼写错误,从this.processImage()tothis.processImage所以它传递的是回调函数而不是processImage函数的结果。

我希望这有帮助!

于 2018-11-17T09:39:48.813 回答