需求背景 ⛰️
目前在学习NodeJs过程中,刚好有个需求需要调用第三方接口拉取几千条详情数据,意味着需要发起几千个请求,如果全部请求同时发出,那将出现大量失败的请求。此时我需要对这些请求做并发限制,并且当出现接口错误时对请求进行错误重试,从而达到尽可能完整的获取这几千条数据。
上代码
// 并发处理库
const { PromisePool } = require('@supercharge/promise-pool');
// 错误重试库
const promiseRetry = require('promise-retry')
/**
* Mock用户数据
*/
const MOCK_USERS = [
{ name: 'Marcus' },
{ name: 'Norman' },
{ name: 'Christian' }
];
/**
* 随机布尔值
* @param {number} [trueRate=.5] 返回true的比率,默认50%
* @returns {boolean} true 或 false
*/
const randomBoolean = (trueRate) => Math.random() > (1 - trueRate)
// Mock用户详情接口
const MockApiUserDetail = (data) => new Promise((resolve, reject) => setTimeout(() => {
// 如果为"true",接口返回成功
if (randomBoolean() === true) {
resolve(data)
} else {
reject('error')
}
}, 1000));
PromisePool
// 设置并发数
.withConcurrency(1)
// 设置并发池需要的数据
.for(MOCK_USERS)
// 通过迭代项目开始处理承诺池,并通过异步“回调”函数运行每个项目
.process(async (userData, index, pool) => {
const userInfo = await promiseRetry((retry, attempt) => {
console.log(`${userData.name}重试次数: ${attempt}`)
return MockApiUserDetail(userData).catch(retry)
}, {
// 设置重试次数
retries: 10
})
console.log(`请求${userData.name}成功 ${JSON.stringify(userInfo)}`)
console.log('--------------')
return userInfo
})
.then(({ results, errors }) => {
console.log(`请求池结果 ${JSON.stringify(results)}`)
console.log(`请求池错误 ${JSON.stringify(errors)}`)
})