Как я могу гарантировать, что моя программа остановится, пока не будут разрешены мои запросы axios? - PullRequest
2 голосов
/ 04 октября 2019

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

// handles item creation
handleCreate = async (data) => {
    let id = await axios({
                            method: 'post',
                            url: <item_creation_URL>,
                            data: data
                        })
                        .then(res => {
                            return res.data();
                        })
                        .catch(err => {
                            this.handleErrors(err);
                        })
    return id;
}

// handles image uploads for a specific item
handleUpload = async (fd, itemId) => {
    let response = await axios({
                                 method: 'post',
                                 url: <img_upload_URL>,
                                 headers: {
                                     'content-type': 'multipart/form-data'
                                 },
                                 data: fd
                               })
                               .then(res => {
                                   return res;
                               })
                               .catch(err => {
                                   this.handleErrors(err.response.data);
                               });
    return response;
}

// prepares and sends the data to the server to create a new item
handleSubmit = event => {

    event.preventDefault();

    this.setState({ loading: true });

    // data needed to make an item on firebase
    const itemData = {
        name       : this.state.name,
        desc       : this.state.desc,
        cover      : this.state.coverImgIndex,
        visibleTo  : this.state.visibleTo,
        assignedTo : this.state.assignedTo,
        photos     : this.state.photos
    }

    // create a new item using the data
    let itemId = this.handleCreate(itemData);

    // upload the photos
    if (!this.state.errors){
        for (let i=0; i < this.state.uploadedFiles.length; i++) {
            let file = this.state.uploadedFiles[i];
            let fd = new FormData();
            fd.append('file', file, file.name);

            // send each file as its own upload request
            this.handleUpload(fd, itemId);

            if (this.state.errors) break;
        }
    }

    // submission was successful
    if (!this.state.errors){
        this.setState({ loading : false });
    }
}

Я провел онлайн-исследование и подумал, что смогу достичь желаемого эффекта, заключив каждый запрос axios в блок async с await. Тем не менее, кажется, что выполнение выполняется без ожидания завершения каждого запроса.

Я довольно новичок в использовании Promise s в Javascript. Здесь я что-то не так делаю?

1 Ответ

2 голосов
/ 04 октября 2019

вы сделали handleCreate() и handleUpload() функции асинхронными. поэтому, когда вы вызываете эти функции, используйте await, если вы должны идти дальше после окончания axios.

Как это

// handles item creation
handleCreate = async data => {
  try {
    const res = await axios({
      method: "post",
      url: `<item_creation_URL>`,
      data: data
    });
    return res.data();
  } catch (err) {
    throw err;
  }
};

// handles image uploads for a specific item
handleUpload = async (fd, itemId) => {
  try {
    const res = await axios({
      method: "post",
      url: `<img_upload_URL>`,
      headers: {
        "content-type": "multipart/form-data"
      },
      data: fd
    });
    return res;
  } catch (err) {
    throw err.response.data;
  }
};

// prepares and sends the data to the server to create a new item
handleSubmit = event => {
  event.preventDefault();

  // data needed to make an item on firebase
  const { name, desc, cover, visibleTo, assignedTo, photos } = this.state;
  this.setState({ loading: true });
  this._asyncSubmit({ name, desc, cover, visibleTo, assignedTo, photos });
};

_asyncSubmit = async itemData => {
  try {
    // create a new item using the data
    const itemId = await this.handleCreate(itemData);
    for (let i = 0; i < this.state.uploadedFiles.length; i++) {
      const file = this.state.uploadedFiles[i];
      let fd = new FormData();
      fd.append("file", file, file.name);
      // send each file as its own upload request
      await this.handleUpload(fd, itemId);
    }
  } catch(err) {
    // you can handle errors here
    this.handleErrors(err);
  }
  this.setState({ loading: false });
};
...