返回

React 应用中如何优化 S3 文件列表和元数据获取?

javascript

React应用中优化S3文件列表和元数据获取

问题分析

在构建React应用时,我们可能会遇到一个常见问题,即在从S3获取文件列表后,还需要检索每个文件的用户定义元数据。但是,使用传统的异步回调方法会导致延迟和过时的列表显示。

解决之道

为了解决这一问题,我们可以采取以下步骤:

使用Promise.all

为了确保在更新listFiles状态之前所有headObject调用都已完成,我们可以使用Promise.all。这将创建一个Promise,等待所有子Promise完成。

正确更新状态

getUserMetaData函数中,我们需要使用setListFiles函数来更新listFiles状态,而不是直接返回修改后的数组。

减少HTTP调用

listObjectsV2调用中,我们可以使用Delimiter参数仅检索文件的键和大小。这可以减少对每个文件的重复headObject调用。

代码优化

import React, { useState, useEffect } from "react";
import AWS from "aws-sdk";

function App() {

  const s3 = new AWS.S3({
    credentials: {
      accessKeyId: process.env.REACT_APP_AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.REACT_APP_AWS_SECRET_ACCESS_KEY,
      region: process.env.REACT_APP_AWS_REGION,
    },
  });

  const params = {
    Bucket: "abc",
    Delimiter: "/",
  };

  const [listFiles, setListFiles] = useState([]);

  useEffect(() => {
    s3.listObjectsV2(params, (err, data) => {
      if (err) {
        console.log(err, err.stack);
      } else {
        Promise.all(
          data.Contents.map((aFile) =>
            new Promise((resolve, reject) => {
              const headParams = {
                Bucket: "abc",
                Key: aFile.Key,
              };

              s3.headObject(headParams, (err1, data1) => {
                if (err1) {
                  reject(err1);
                } else {
                  aFile.user_metadata_1 = data1.Metadata["user_metadata_1"];
                  resolve();
                }
              });
            })
          )
        )
          .then(() => setListFiles(data.Contents))
          .catch((err) => console.log(err));
      }
    });
  }, []);

  return (
    <>
      <div className="App">
        <table>
          <tr>
            <th>user_metadata_1</th>
            <th>Document Name</th>
            <th>Size</th>
          </tr>

          {listFiles &&
            listFiles.map((name, index) => {
              return (
                <tr key={index}>
                  <td>{name.user_metadata_1}</td>
                  <td>{name.Key}</td>
                  <td>{name.Size}</td>
                </tr>
              );
            })}
        </table>
      </div>
    </>
  );
}

export default App;

结论

通过实施这些优化,我们可以有效地解决在React应用中从S3获取文件列表和元数据时遇到的问题。这将导致更快速、更准确的显示,提高用户体验。

常见问题解答

1. 如何避免过时的列表显示?
使用Promise.all确保在更新listFiles状态之前,所有headObject调用都已完成。

2. 如何正确更新状态?
使用setListFiles函数更新listFiles状态,而不是直接返回修改后的数组。

3. 如何减少HTTP调用?
listObjectsV2调用中使用Delimiter参数仅检索文件的键和大小,从而减少重复的headObject调用。

4. 为什么优化性能很重要?
性能优化对于避免滞后和提升用户体验至关重要。

5. 有其他优化策略吗?
其他策略包括使用批处理、缓存和选择最合适的存储类。