题目:调接口时限制每次最多只能有两个接口同时请求,最终让所有接口都完成请求。
思考:
计数:每次调接口加一,调完减一,如果正在执行的接口 >= 2,则等待,否则继续执行
如何阻止继续请求接口?
第一步模拟一个调接口的方法做测试,设置一个定时器,promise延迟返回,模拟调接口的异步情况:
async function makeRequest(url) {
console.log(`Start Request to ${url}`)
return new Promise(resolve => {
setTimeout(()=> {
resolve(`Response from ${url} ---------`);
}, Math.random()*2000);
});
}
调接口,假如有五个接口需要进行控制,我希望能定义一个方法类,调用这个实例方法实现最多同时两个接口在调用,我们定义类 MethodClass,里面有一个方法 callApi 是用来做控制,
接下来就是核心代码部分,这个类是如何实现的?
class MethodClass {
constructor(interfaceNum) {
this.currentRequests = 0;
this.maxNum = interfaceNum
}
async callApi(apiFunction) {
// 确保同时调用的接口数量不超过this.maxNum
if (this.currentRequests >= this.maxNum) {
await new Promise(resolve => {
const intervalId = setInterval(() => {
// 运行代码可以看到这里会循环打印控制的最大接口数,
// 比如控制最多两个接口,等于2时,就会进入定时器等待,
// 因为写了await,所以一定会进入等待状态,每100ms判断一下currentRequests是否更新
console.log(this.currentRequests)
if (this.currentRequests < this.maxNum) {
// 直到 currentRequests 小于2时,清除定时器,等待的这个promise才能进行resolve
clearInterval(intervalId);
resolve();
}
}, 100);
});
}
this.currentRequests++;
try {
const results = await apiFunction();
console.log(results)
return results;
} finally {
// 一个完整的接口调用完毕之后计数减一,定时器里获取到最新的 currentRequests 值,判断是否继续等待
this.currentRequests--;
}
}
}
具体使用的时候:
const methodClass = new MethodClass(2); //最多同时发送两个请求
async function run() {
const urls =['https://api.example.com/1','https://api.example.com/2', 'https://api.example.com/3',
'https://api.example.com/4', 'https://api.example.com/5']
for(const url of urls) {
methodClass.callApi(() => makeRequest(url));
}
}
run()
总结:
遇到写代码的情况需要先思考需求是什么,实现步骤思路是怎么样的,可以先用文字描述出来当做注释,再进行后续的代码书写。
class 怎么写?
在类中,constructor是构造函数的意思,它被调用 来创建并初始化一个类的实例。js 中,会在创建一个类的新实例时自动调用。constructor函数可以用来初始化实例对象。例如:
class Person {
constructor(name) {
this.name = name
}
}
const p1 = new Person('Mary')
console.log(p1.name)