链接承诺,包括获取

Chaining promises including fetch

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

我认为链接承诺应该可以完成这项工作,但我做不到。

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

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

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

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

我检查了第一个承诺是否有效,并向第二个承诺发送了一个 'prefilled' 表单数据。然后 post 请求起作用,并且 returns 响应,因为我可以看到状态变量 photo 在未来的某个时间更新。然而,promise 本身 returns 一个无效的表单数据,即使没有链接:

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

returns 没有。

您已经很好地执行了 promise 链接。您只需要 return 该承诺链的结果而不是来自您的函数的 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()
  }
}