У меня есть приложение Angular 4, в котором я читаю изображение и пытаюсь передать строку base64 в другую переменную, однако у меня возникла проблема из-за асинхронного характера этого - image.src пуст, и поэтому значение правильно передано в объект изображения?
ngAfterViewInit(): void {
let image = new Image();
var promise = this.getBase64(fileObject, this.processImage());
promise.then(function(base64) {
console.info(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 или использовать async await? В чем проблема на +400 ???
Итак, вы хотите использовать обещание, но не хотите ждать, пока оно будет выполнено.





promise.then - это асинхронная функция, что означает, что код появляется после того, как сначала будет выполнен этот оператор, а затем будет выполнена функция обратного вызова в then. Итак, вы должны переместить свой код в обратный вызов then.
promise.then((base64: string) => {
console.info(base64); // outputs string e.g 'data:image/jpeg;base64,........'
console.info(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.
Кажется, работает, однако я получаю Type '{}' is not assignable to type 'string', хотя уверен, что переменная base64 является строкой. Я также объявил изображение как любое, например, public image: any - по какой причине я получаю ошибку машинописного текста в моем редакторе? (хотя вроде работает ...)
Вы можете явно определить base64 как строку, так как вы знаете, что это будет строка во время выполнения. Так что попробуйте function(base64: string)
Поскольку код по своей природе является асинхронный, вам придется дождаться результата, если вы хотите его использовать. В вашем случае вам придется подождите, пока ваше обещание будет выполнено. Итак, ваш код должен выглядеть так:
ngAfterViewInit(): void {
let image = new Image();
var promise = this.getBase64(this.fileObject, this.processImage);
promise.then(function(base64: string) {
console.info(base64);
image.src = base64;
let editor = new PhotoEditorSDK.UI.ReactUI({
container: this.editor.nativeElement
editor: {
image: image
}
});
});
}
Я изменил следующее:
ReactUI в обратный вызов обещанияbase64 как stringgetBase64, от 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 }
});
});
}
Почему бы вам просто не поместить
let image = new Image();иimage.src = base64;в функцию обратного вызова обещания?