【问题标题】:How do I ensure that my program halts until my axios requests have been resolved?如何确保我的程序停止,直到我的 axios 请求得到解决?
【发布时间】:2020-02-02 12:57:25
【问题描述】:

我正在开发一个使用 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 请求用await 包装在async 块中来达到预期的效果。 但是,执行似乎无需等待每个请求完成即可进行。

我对在 Javascript 中使用 Promises 还很陌生。我在这里做错了吗?

【问题讨论】:

  • async 函数也必须是 awaited。 handle*await axios 调用,但您的循环不是 awaiting handle* 调用。
  • @deceze 我确实尝试过写let itemId = await this.handleCreate(itemData);,但我收到了错误Parsing error: Can not use keyword 'await' outside an async function
  • 不言自明的错误消息,无论您使用await in 需要async 在其签名中的任何功能。您已经这样做了,例如 inside handleCreate 函数。必须在你实际调用它的地方做它

标签: javascript reactjs promise async-await axios


【解决方案1】:

您使 handleCreate()handleUpload() 函数异步。 因此,当您调用这些函数时,如果您应该在 axios 结束后继续,请使用 await

像这样

// 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 });
};

【讨论】:

  • 我试过了,但我仍然收到错误 Parsing error: Can not use keyword 'await' outside an async function 的行 const itemId = await this.handleCreate(itemData);
  • 由于我的服务器响应方式,我不得不进行一些小改动,但它现在可以正常工作了——非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
  • 1970-01-01
相关资源
最近更新 更多