在 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函数中 |
动态队列 |
动态添加的不确定数量请求 |
灵活扩展 |
需要额外管理队列逻辑 |
注意事项
-
错误处理:必须用
.catch()
或try/catch
捕获异常,避免中断后续请求。 - 依赖传递:如果后一个请求需要前一个的结果,通过返回值传递数据:
await request("/api/first")
.then((result1) => request(`/api/second?data=${result1}`))
-
性能优化:若请求间无依赖,可用
Promise.all()
并行处理提升效率。