Почему ждать обещание не ждать обещание решить? - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь научиться правильно использовать асинхронное ожидание, но меня это немного смущает.

В фрагментах я пытаюсь создать массив объектов, содержащих необходимую информацию о файле, который я загружаю в компонент.Проблема в том, что объекты в this.fileInfo точно не ожидают обещания вернуть закодированные изображения, возвращая этот вывод, как я console.log this.fileInfo:

output

Как видите, ключевым изображением является ZoneAwarePromise, значение которого не определено.Не могли бы вы помочь мне исправить это?

Функция build ()

async build(e) {
    let files = e.target.files;
    this.j = Array.from(files);
    this.fileInfo = await this.j.reduce((acc, cur) => [
        ...acc, {
            name: cur.name.replace(/^.*\\/, ""),
            sizeunit: this.getSize(cur.size),
            extention: cur.name.split(/\.(?=[^\.]+$)/).slice(-1).pop().toString(),
            image: this.previewFile(cur)
        }
    ], [])
    console.log(await this.fileInfo);
}

Обещание

async previewFile(file) {

    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
        return new Promise((res) => {
            res(reader.result)
        }).then( res => res);
    };
}

1 Ответ

0 голосов
/ 27 ноября 2018

Вы ничего не ожидаете в этой функции: async previewFile(file).Возможно, вы предполагаете, что возвращение нового Promise где-нибудь по строкам вашего кода сделает его Promise.В этом конкретном случае это не будет работать, потому что он находится внутри делегата (onload), который не будет выполняться в рамках вашей функции previewFile().

Вы можете потерять асинхронный модификатор, потому что вы можетевместо этого верните обещание:

previewFileAsync(file) {
    // the async modifier keyword is not necessary,
    // because we don't need to await anything.
    return new Promise((res) => {
         const reader = new FileReader();
         reader.readAsDataURL(file);
         reader.onload = () => res(reader.result);
    });
}

Когда вы вызываете это, вы можете ожидать его внутри цикла:

async buildAsync(e) {
    let files = e.target.files;
    for(let i = 0; i < files.length; i++) {
        const file = files[i];
        const preview = await previewFileAsync(file);
        // Do something with preview here...
    }
}

Конечно, вы можете выполнить диапазон обещаний, чтобы учесть некоторыесвоего рода параллелизм, но это поможет вам начать.

Я добавил суффикс Async к вашему методу, чтобы вызывающая сторона знала, что этого можно ожидать.Он не делает ничего особенного, но помогает прояснить ваш код.Вы можете использовать любой суффикс, который вы считаете правильным.Я просто привык к суффиксу Async.

Редактировать

Пример асинхронной логики Stackblitz

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...