Функция обещания с FileReader преждевременно разрешается

Я открываю файл, чтобы прочитать его содержимое:

convertBlobToBase64(blob){
    var convertPromise = new Promise(function(resolve, reject){
      var fileReader = new FileReader();
      fileReader.onload = function() {
          var dataUrl = this.result;
          var base64 = dataUrl.split(',')[1];
          resolve(base64);
      };

      fileReader.readAsDataURL(blob);
    });

    return convertPromise;
  }

Затем я вызываю эту функцию и передаю данные результата, когда она разрешается:

myFunction(audioFile){
    var to64 = this.convertBlobToBase64(audioFile);
    to64.then(function(base64Val){
        var nextPromise = postCall();
        nextPromise.then(//stuff);
        return nextPromise;
    });

    return to64;
} 

Однако, когда я вызываю myFunction, он немедленно возвращает обработанное обещание, которое включает преобразованные данные из convertBlobToBase64, а не неразрешенное обещание, которое должно ожидать на nextPromise, как ожидалось.

Вместо этого myFunction .then вызывается немедленно и терпит неудачу, поскольку у него нет правильных данных. Я неправильно понимаю функцию обещания?

Зачем нужен base64?

Endless 11.05.2018 18:03

@Endless Для отправки аудиоконтента на сервер.

JWiley 11.05.2018 18:22

Разве вы не можете просто отправить его как есть? с FormData? base64 в ~ 3 раза больше по размеру

Endless 12.05.2018 12:44

@Endless, можешь подробнее рассказать об этом? Когда я не кодировал в base64, звук загружался некорректно и отображался как поврежденный. Закачиваю в Dropbox.

JWiley 06.09.2018 05:24
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
791
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Попробуйте этот код:

myFunction(audioFile){
    var to64 = this.convertBlobToBase64(audioFile);
    return to64.then(function(base64Val){
        var nextPromise = postCall();
        return nextPromise.then(//stuff);
    });
} 

это сработало, спасибо. Не могли бы вы объяснить, почему return to64 - это предварительно разрешенное обещание?

JWiley 10.05.2018 20:48

Если это сработает, то вот объяснение. Обещание - это то, что оборачивает значение. Поэтому, когда вы вызываете then для обещания, он, в свою очередь, возвращает новое обещание. Таким образом, строка nextPromise.then(//stuff); просто игнорирует возвращенное обещание. Надеюсь, это понятно.

Anton Harniakou 10.05.2018 20:49

Верно, но почему бы строчке return to64 не быть отложенным обещанием? Почему это уже решено?

JWiley 10.05.2018 20:54

Может быть, решение было таким быстрым, ха-ха. Я имею в виду, что to64 не нужно было ждать вещей, которые войдут в и после then.

Anton Harniakou 10.05.2018 21:02

Кстати, вам не нужно переносить еще одно обещание в функцию. Вы можете использовать свой postCall как функцию разрешения и связать его следующим образом:

myFunction(audioFile){
  return convertBlobToBase64(audioFile)
    .then(base64Val => postCall())
    .then(//stuff)
} 

Другие вопросы по теме