Javascript 如何在Resact js ES6中使用Promise.all

Javascript 如何在Resact js ES6中使用Promise.all,javascript,ajax,reactjs,Javascript,Ajax,Reactjs,我想做的是上传文件到服务器上,然后得到上传文件的URL并预览它。文件可以是多个。为此,我编写了以下代码: let filesURL=[]; let promises=[]; if(this.state.files_to_upload.length>0) { for(let i=0; i<this.state.files_to_upload.length; i++) { promises.push(this.uploadFilesOnServer(thi

我想做的是上传文件到服务器上,然后得到上传文件的URL并预览它。文件可以是多个。为此,我编写了以下代码:

 let filesURL=[];
 let promises=[];
 if(this.state.files_to_upload.length>0) {

    for(let i=0; i<this.state.files_to_upload.length; i++) {
        promises.push(this.uploadFilesOnServer(this.state.files_to_upload[i]))
    }

    Promise.all(promises).then(function(result){
        console.log(result);
        result.map((file)=>{
            filesURL.push(file);
        });
    });
    console.log(filesURL);
}
const uploadedFilesURL=filesURL;
console.log(uploadedFilesURL);

您必须在
上执行此操作。然后
承诺的一部分。all()


这就是异步代码的工作方式。您不能期望您的
console.log(fileurl)将正常工作

关于您的代码,有几个问题:

1.
uploadFilesOnServer
必须返回承诺,因为它是异步的。因此:

  uploadFilesOnServer(file)
  {
    let files=[];
    let file_id='';

    const image=file;
    return getImageUrl().then((response) => {
      const data = new FormData();
      data.append('file-0', image);
      const {upload_url}  = JSON.parse(response);
      console.log(upload_url);

      updateProfileImage(upload_url, data).then ((response2) => {
      const data2 = JSON.parse(response2);
      file_id=data2;
      console.log(file_id);
      files.push(file_id);
      console.log(files);
      return files;
        });
    });
  }
2.在您的主要功能主体内,您可以评估
承诺的结果。所有
执行仅在其各自的then
处理程序中进行


作为补充说明,我建议您将es7/功能与一些诸如babel/typescript之类的Transpiler一起使用。这将大大减少编写此类异步代码的嵌套/复杂度。

不,promise是异步的,因此不能按您认为的方式工作。如果希望在承诺完成后执行某项操作,则必须将其放入承诺的
回调中,然后将其放入
回调中。以下是基于您的代码的示例:

uploadFilesOnServer(file) {
  let files=[];
  let file_id='';

  const promise = getImageUrl()
  .then((imageUrlResponse) => {
    const data = new FormData();

    data.append('file-0', file);

    const { upload_url }  = JSON.parse(imageUrlResponse);

    console.log(upload_url);

    return updateProfileImage(upload_url, data);
  })
  .then ((updateImageResponse) => {
    file_id= JSON.parse(updateImageResponse);

    console.log(file_id);

    files.push(file_id);

    console.log(files);

    return files;
  });

  return promise;
}

let filesPromise = Promise.resolve([]);

if(this.state.files_to_upload.length > 0) {
  const promises = this.state.files_to_upload.map((file) => {
    return this.uploadFilesOnServer(file);
  });

  filesPromise = Promise.all(promises).then((results) => {
    console.log(results);

    return [].concat(...results);
  });
}

// This is the final console.log of you (console.log(uploadedFilesURL);)
filesPromise.then((filesUrl) => console.log(filesUrl));
这本书是一本关于ES6的好书

编辑:

下面是示例代码的简单解释:

  • UploadFileOnServer是一个函数,它接收文件,上载文件,并在将来完成上载时以承诺的形式返回文件URL。promise将调用其
    ,然后在获取url时调用
    回调

  • 通过使用map函数,我们创建了一个url承诺列表,即对列表中的每个文件执行
    uploadFilesOnServer
    得到的结果

  • Promise.all
    方法等待列表中的所有承诺完成,加入url结果列表,并使用结果(url列表)创建承诺。我们需要这样做,因为不能保证所有的承诺都能一次完成,为了方便起见,我们需要在一次回调中收集所有结果

  • 我们从
    然后
    回调中获取URL


  • 您需要更多地了解Javascript中的承诺。首先,
    console.log(uploadedFilesURL)将立即执行。解析承诺后需要运行的代码进入
    .then()
    回调。其次,
    Promise.all()
    接受一个promises数组作为参数,同时传递一个包含
    文件id
    类型的数组。Thank alot@Tr1et可能重复。您给定的代码片段解决了这个问题。我在上面的理解是,首先我们将“files\u to\u upload”数组映射到“file”并将其传递到“uploadFileOnServer”。此函数返回包含“文件”数组的承诺。然后在每个promise上调用promise.all并将所有数据连接到一个数组中。现在“filePromise”将拥有所有组合数据,并且可以访问filePromise的整个“.then()”。请告诉我,如果我得到了正确的或纠正我在哪里得到了错误。谢谢我在答案中添加了一个解释,因为它有点长。有什么你们不明白的吗?现在,我想知道哪些文件无法上传到服务器上。这就是承诺失败的原因。我该怎么做?
      uploadFilesOnServer(file)
      {
        let files=[];
        let file_id='';
    
        const image=file;
        return getImageUrl().then((response) => {
          const data = new FormData();
          data.append('file-0', image);
          const {upload_url}  = JSON.parse(response);
          console.log(upload_url);
    
          updateProfileImage(upload_url, data).then ((response2) => {
          const data2 = JSON.parse(response2);
          file_id=data2;
          console.log(file_id);
          files.push(file_id);
          console.log(files);
          return files;
            });
        });
      }
    
    uploadFilesOnServer(file) {
      let files=[];
      let file_id='';
    
      const promise = getImageUrl()
      .then((imageUrlResponse) => {
        const data = new FormData();
    
        data.append('file-0', file);
    
        const { upload_url }  = JSON.parse(imageUrlResponse);
    
        console.log(upload_url);
    
        return updateProfileImage(upload_url, data);
      })
      .then ((updateImageResponse) => {
        file_id= JSON.parse(updateImageResponse);
    
        console.log(file_id);
    
        files.push(file_id);
    
        console.log(files);
    
        return files;
      });
    
      return promise;
    }
    
    let filesPromise = Promise.resolve([]);
    
    if(this.state.files_to_upload.length > 0) {
      const promises = this.state.files_to_upload.map((file) => {
        return this.uploadFilesOnServer(file);
      });
    
      filesPromise = Promise.all(promises).then((results) => {
        console.log(results);
    
        return [].concat(...results);
      });
    }
    
    // This is the final console.log of you (console.log(uploadedFilesURL);)
    filesPromise.then((filesUrl) => console.log(filesUrl));