react面试题

636 阅读1分钟

在 React 中,如果需要按顺序执行多个接口请求?

1.使用 async/await 串行化请求

import axios from "axios";

const fetchSequentialData = async () => {
  try {
    // 第一个请求
    const response1 = await axios.get("https://api.example.com/endpoint1");
    console.log("Response 1:", response1.data);
    // 第二个请求依赖第一个请求的结果
    const response2 = await axios.get(`https://api.example.com/endpoint2?id=${response1.data.id}`);
    console.log("Response 2:", response2.data);
    // 第三个请求依赖第二个请求的结果
    const response3 = await axios.get(`https://api.example.com/endpoint3?id=${response2.data.id}`);
    console.log("Response 3:", response3.data);
  } catch (error) {
    console.error("Error during requests:", error);
  }
};
fetchSequentialData();

2.使用 Promise 链

import axios from "axios";

axios.get("https://api.example.com/endpoint1")
  .then(response1 => {
    console.log("Response 1:", response1.data);
    return axios.get(`https://api.example.com/endpoint2?id=${response1.data.id}`);
  })
  .then(response2 => {
    console.log("Response 2:", response2.data);
    return axios.get(`https://api.example.com/endpoint3?id=${response2.data.id}`);
  })
  .then(response3 => {
    console.log("Response 3:", response3.data);
  })
  .catch(error => {
    console.error("Error during requests:", error);
  });

3.使用 for 循环和 async/await

import axios from "axios";

const endpoints = [
  "https://api.example.com/endpoint1",
  "https://api.example.com/endpoint2",
  "https://api.example.com/endpoint3",
];
const fetchSequentially = async () => {
  try {
    for (const endpoint of endpoints) {
      const response = await axios.get(endpoint);
      console.log(`Response from ${endpoint}:`, response.data);
    }
  } catch (error) {
    console.error("Error during requests:", error);
  }
};

4.使用 async/await 和 Promise.all(最终解决方案)

import axios from "axios";

const endpoints = [
  "https://api.example.com/endpoint1",
  "https://api.example.com/endpoint2",
  "https://api.example.com/endpoint3",
];
const fetchSequentiallyWithAll = async () => {
  const results = [];
  for (const endpoint of endpoints) {
    const response = await axios.get(endpoint); // 按顺序等待每个请求完成
    results.push(response.data);
  }
  // 将所有结果传入 Promise.all 做进一步处理(例如并行保存、进一步请求)
  await Promise.all(results.map(data => {
   return axios.post("https://api.example.com/save", data); // 示例并行处理
  }));
  console.log("All data processed.");
};
fetchSequentiallyWithAll();

在使用 Promise.all 时,如果其中一个 Promise 被拒绝(rejected),默认情况下,整个 Promise.all 会立即中止并返回该错误。但在某些场景下,我们希望即使某个接口失败,也不会影响其他接口的执行。

1.在每个接口的 Promise 上调用 .catch 方法捕获错误,这样即使某个接口失败,它也会返回一个被处理的结果,而不会中断整个 Promise.all。

import axios from "axios";

const endpoints = [
  "https://api.example.com/endpoint1",
  "https://api.example.com/endpoint2",
  "https://api.example.com/endpoint3",
];
const fetchWithErrorHandling = async () => {
  const promises = endpoints.map(endpoint =>
    axios.get(endpoint).catch(error => {
      console.error(`Error fetching ${endpoint}:`, error);
      return { error: true, endpoint }; // 返回错误信息而不是让 Promise 失败
    })
  );
  const results = await Promise.all(promises);
  console.log("Results:", results);
  // 结果中包含成功的数据和失败的信息
};
fetchWithErrorHandling();
  1. 包装每个 Promise 的状态 将每个 Promise 包装成一个始终成功的形式,返回其状态和结果(成功或失败),这样可以在结果中区分成功和失败的情况。 3.用 Promise.allSettled(推荐方法) Promise.allSettled 是专门为这种场景设计的。它会等待所有 Promise 完成,无论是成功还是失败,并返回每个 Promise 的状态和结果。
import axios from "axios";

const fetchAllWithSettled = async () => {
  const promises = endpoints.map(endpoint => axios.get(endpoint));
  const results = await Promise.allSettled(promises);
  results.forEach(result => {
    if (result.status === "fulfilled") {
      console.log("Success:", result.value.data);
    } else {
      console.error("Failed:", result.reason);
    }
  });
};
fetchAllWithSettled();