React async / await не ожидает в вызывающей функции — но вызываемая функция выполняется правильно

#reactjs #async-await

#reactjs #async-await

Вопрос:

У меня есть метод загрузки изображений в моем компоненте react, который вызывает вспомогательный метод в отдельном helpers.js класс для обработки фактической загрузки, чтобы я мог повторно использовать этот метод в другом месте моего приложения.

Компонент react вызывает вспомогательный метод, вспомогательный метод выполняет свою работу по сохранению файла на сервере, все хорошо …. но исходный метод не ожидает разрешения обещания. Я уверен, что мне не хватает чего-то небольшого, но я не вижу этого.

Я прочитал все подобные вопросы здесь и реализовал то, что, как я думал, исправит это, сделал много модификаций и рефакторинга, внедрил синтаксис await в вспомогательном методе, снова вернул его к синтаксису promise и т.д. Но безрезультатно.

//Вызывающий метод из компонента react:

 async  _uploadPicture(e) {

try {
  const pictureUploadResponse = await HelperMethods.uploadPicture(e);

  if (pictureUploadResponse.success) { //<=======**PUKES HERE**

    console.log(pictureUploadResponse.pictureFullPath);

    this.setState({
      picture: pictureUploadResponse.picture,
      pictureFullPath: pictureUploadResponse.pictureFullPath,
      errorEditMessage: pictureUploadResponse.message,
    });


    console.log(this.state.pictureFullPath);

  } else {

    this.setState({
      errorEditMessage: pictureUploadResponse.message
    });

  }

} catch (err) {

  // error 
  console.log(err);

}
  

}

// вспомогательный метод отлично справляется со своей работой … // строка console.log(response.message) выводится просто отлично…изображение находится на сервере, как и ожидалось.

// Метод вспомогательного класса

  static uploadPicture =  (e) => {

        let formData = new FormData();
        formData.append('picToUpload', e.target.files[0]);

        console.log("upload control 1");

        try {

              const settings = {
                    credentials: 'include',
                    method: 'POST',
                    body: formData,
              };

              fetch(envSettings.API_URI(GLOBALS.ENVIRONMENT)   '/utils/uploadpicture', settings)
                    .then(res1 => { return res1.json() })
                    .then(response => {

                          if (response.success) {
                                console.log("upload control 2");
                                console.log(response.message);
                                return {
                                      success: true,
                                      message: response.message,
                                      picture: response.imageUrl,
                                      pictureFullPath: envSettings.IMAGE_ROOT_URI(GLOBALS.ENVIRONMENT)   response.imageUrl,
                                }
                          } else {
                                return {
                                      success: false,
                                      message: response.message,
                                }
                          }
                    }).catch(err => {
                          console.log("error uploading image: "   err)
                          return {
                                success: false,
                                message: err,
                          }
                    });
        } catch (err) {
              console.log(err)
              return {
                    success: false,
                    message: err,
              }
        }

  }
  

Но вызывающая функция не ожидает и попадает во внешний блок catch… Почему она не ожидает?

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

Ответ №1:

Чтобы await сработал, вам необходимо вернуть обещание из вашего метода вспомогательного класса. В данный момент вы запускаете обещание внутри функции и не возвращаете его, таким образом, ожидание в родительском классе не ожидает внутреннего обещания. Чтобы устранить эту проблему, верните выборку.

 return fetch(envSettings.API_URI(GLOBALS.ENVIRONMENT)   '/utils/uploadpicture', settings).then(...).then(...).catch(...)
  

Комментарии:

1. Спасибо. Я знал, что это было что-то маленькое, чего я просто не видел.

2. Спасибо, это то, что я искал. Случайно я пропустил возврат 🙂