Skip to content

请求多个api接口

TIP

同一个页面请求多个接口,也是比较常见的,下面推荐几种处理,避免重复代码

三种场景处理多 API 请求

方案一:并发请求(推荐)

js
// 正确写法:用箭头函数延迟执行,并保留错误信息
Promise.all([
  List().catch(err => { console.error('List请求失败', err); return null }),
  page({count: 0}).catch(err => { console.error('page请求失败', err); return null })
])
.then(([result1, result2]) => {
  // 即使某个请求失败,也能拿到null而不是undefined
  console.log('结果1:', result1);
  console.log('结果2:', result2);
})
.catch(err => {
  // 所有请求都成功才不会进入这里
  console.error('所有请求都失败了', err);
});
// 正确写法:用箭头函数延迟执行,并保留错误信息
Promise.all([
  List().catch(err => { console.error('List请求失败', err); return null }),
  page({count: 0}).catch(err => { console.error('page请求失败', err); return null })
])
.then(([result1, result2]) => {
  // 即使某个请求失败,也能拿到null而不是undefined
  console.log('结果1:', result1);
  console.log('结果2:', result2);
})
.catch(err => {
  // 所有请求都成功才不会进入这里
  console.error('所有请求都失败了', err);
});

方案二:顺序请求(按顺序执行)

js
// 如果后一个请求依赖前一个请求的结果
List()
  .then(result1 => {
    console.log('第一个请求结果:', result1);
    return page({count: result1.total}); // 假设依赖第一个请求的total字段
  })
  .then(result2 => {
    console.log('第二个请求结果:', result2);
  })
  .catch(err => {
    console.error('任一请求失败', err);
  });
// 如果后一个请求依赖前一个请求的结果
List()
  .then(result1 => {
    console.log('第一个请求结果:', result1);
    return page({count: result1.total}); // 假设依赖第一个请求的total字段
  })
  .then(result2 => {
    console.log('第二个请求结果:', result2);
  })
  .catch(err => {
    console.error('任一请求失败', err);
  });

方案三:并发请求(带错误处理)

js
// 使用Promise.allSettled(ES2020)获取所有请求的结果(无论成功失败)
Promise.allSettled([List(), page({count: 0})])
  .then(results => {
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        console.log(`第${index+1}个请求成功`, result.value);
      } else {
        console.error(`第${index+1}个请求失败`, result.reason);
      }
    });
  });
// 使用Promise.allSettled(ES2020)获取所有请求的结果(无论成功失败)
Promise.allSettled([List(), page({count: 0})])
  .then(results => {
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        console.log(`第${index+1}个请求成功`, result.value);
      } else {
        console.error(`第${index+1}个请求失败`, result.reason);
      }
    });
  });

高级优化:请求超时控制

js
// 添加超时控制,防止某个请求卡死
const fetchWithTimeout = (promise, timeout = 5000) => {
  return Promise.race([
    promise,
    new Promise((_, reject) => 
      setTimeout(() => reject(new Error('请求超时')), timeout)
    )
  ]);
};

// 使用带超时的请求
Promise.all([
  fetchWithTimeout(List()),
  fetchWithTimeout(page({count: 0}))
])
.then(([result1, result2]) => {
  // 处理结果
})
.catch(err => {
  console.error('请求超时或失败', err);
});
// 添加超时控制,防止某个请求卡死
const fetchWithTimeout = (promise, timeout = 5000) => {
  return Promise.race([
    promise,
    new Promise((_, reject) => 
      setTimeout(() => reject(new Error('请求超时')), timeout)
    )
  ]);
};

// 使用带超时的请求
Promise.all([
  fetchWithTimeout(List()),
  fetchWithTimeout(page({count: 0}))
])
.then(([result1, result2]) => {
  // 处理结果
})
.catch(err => {
  console.error('请求超时或失败', err);
});

程序员小洛文档