js 如何在前一个请求结束之后发起请求

时间:2025-03-12 15:47:34

在 JavaScript 中,可以通过以下方法确保前一个请求完成后再发起下一个请求:


方法 1:使用 Promise 链式调用

将每个请求封装成返回 Promise 的函数,通过 .then() 按顺序执行:

// 模拟异步请求函数
function request(url) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("请求完成:", url);
      resolve(`数据来自 ${url}`);
    }, 1000);
  });
}

// 链式调用按顺序执行
request("/api/first")
  .then((result1) => {
    console.log("第一个结果:", result1);
    return request("/api/second");
  })
  .then((result2) => {
    console.log("第二个结果:", result2);
    return request("/api/third");
  })
  .catch((error) => {
    console.error("请求失败:", error);
  });

方法 2:使用 async/await

通过 async 函数和 await 关键字实现同步风格的异步代码:

async function sequentialRequests() {
  try {
    const result1 = await request("/api/first");
    console.log("第一个结果:", result1);

    const result2 = await request("/api/second");
    console.log("第二个结果:", result2);

    const result3 = await request("/api/third");
    console.log("第三个结果:", result3);
  } catch (error) {
    console.error("请求失败:", error);
  }
}

sequentialRequests();

方法 3:动态队列控制

如果需要动态管理多个请求(数量不确定),可以用队列实现:

class RequestQueue {
  constructor() {
    this.queue = [];
    this.isProcessing = false;
  }

  add(requestFn) {
    this.queue.push(requestFn);
    if (!this.isProcessing) this.process();
  }

  async process() {
    this.isProcessing = true;
    while (this.queue.length > 0) {
      const requestFn = this.queue.shift();
      try {
        await requestFn();
      } catch (error) {
        console.error("请求失败:", error);
      }
    }
    this.isProcessing = false;
  }
}

// 使用示例
const queue = new RequestQueue();

queue.add(() => request("/api/first"));
queue.add(() => request("/api/second"));
queue.add(() => request("/api/third"));

关键区别

方法

适用场景

优点

缺点

Promise链

固定顺序的少量请求

代码简洁

嵌套过多可读性下降

async/await

明确的顺序请求

代码直观易读

需包裹在async函数中

动态队列

动态添加的不确定数量请求

灵活扩展

需要额外管理队列逻辑


注意事项

  1. 错误处理:必须用 .catch()try/catch 捕获异常,避免中断后续请求。
  2. 依赖传递:如果后一个请求需要前一个的结果,通过返回值传递数据:
await request("/api/first")
  .then((result1) => request(`/api/second?data=${result1}`))
  1. 性能优化:若请求间无依赖,可用 Promise.all() 并行处理提升效率。