【问题标题】:Chaining promises including fetch链接承诺,包括 fetch
【发布时间】:2020-11-09 22:39:42
【问题描述】:

我有一个带有文件作为输入的 React 表单,onFileChange 保存了setFile(e.target.files[0])(并且还切换了一个布尔值change)。然后当我提交表单时:

  • 我首先想把这个文件上传到云端(这里是 Cloudinary),
  • 等待响应对象(即我正在寻找的urlpublic_id
  • 然后我将此对象(url'public_id)添加到表单数据以发布到数据库后端。

我认为链接承诺应该可以完成这项工作,但我无法实现。

在我的onFormSubmit 中,我首先定义了一个捕获非异步数据的承诺:

function init(fd){
  fd.append('input1'...)
  return Promise.resolve(fd)
}

所以我可以重用表单数据来提供下一个承诺upLoadToCL,它应该“通常”将响应对象从云异步附加到表单数据,其中:

init(new FormData).then(res => upLoadToCL(res)).then(res=> ...)

function upLoadToCL(fd) {
      if (changed) {
        // send 'file' (saved as state variable after input) to the cloud
        const newfd = new FormData();
        newfd.append("file", file);
        newfd.append("upload_preset", "ml_default");
        fetch(`https://api.cloudinary.com/v1_1/${cloudName}/upload`, {
          method: "POST",
          body: newfd,
        })
          .then((res) => res.json())
          // append the formdata argument 'fd' with the result
          .then((res) => {
            setPhoto(res);
            fd.append("event[directCLUrl]", res.url);
            fd.append("event[publicID]", res.public_id);
          })
          .catch((err) => {
            throw new Error(err);
          });
        return Promise.resolve(fd);
      }
    }

我检查了第一个承诺是否有效,并向第二个承诺发送了一个“预填充”表单数据。然后发布请求起作用,并返回一个响应,因为我可以看到状态变量photo 在未来某个时间会更新。然而,即使没有链接,promise 本身也会返回一个 void formdata:

upLoadToCL(new FormData())
  .then(res=> {
    for (let [k,v] of res){
      console.log(k,v)
    }
  })

什么都不返回。

【问题讨论】:

    标签: javascript reactjs es6-promise fetch-api


    【解决方案1】:

    您已经很好地执行了承诺链接。您只需要从您的函数返回该承诺链的结果,而不是 Promise.resolve(fd)

    function upLoadToCL(fd) {
      if (changed) {
        // send 'file' (saved as state variable after input) to the cloud
        const newfd = new FormData();
        newfd.append("file", file);
        newfd.append("upload_preset", "ml_default");
        return fetch(`https://api.cloudinary.com/v1_1/${cloudName}/upload`, {
    //  ^^^^^^
          method: "POST",
          body: newfd,
        })
        .then((res) => res.json())
        .then((res) => {
          setPhoto(res);
          // append the formdata argument 'fd' with the result
          fd.append("event[directCLUrl]", res.url);
          fd.append("event[publicID]", res.public_id);
          return fd;
    //    ^^^^^^ fulfilling the promise with the updated fd
        });
      } else {
        return Promise.resolve(fd);
    //  ^^^^^^ always returning a promise for fd from uploadToCL()
      }
    }
    

    【讨论】:

    • 字面上写了同样的东西,然后你评论了:) @NevD - 我的规则是在使用 Promise 或 async/await 时始终记住返回一个值。
    • @NickHolden 确实,that's the first rule :-)
    • 这很好用!谢谢,谢谢链接
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 2023-01-27
    • 2015-01-21
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    相关资源
    最近更新 更多