竞速web请求递归承诺



我有一个网页请求,有时在0.1秒内完成,有时在20秒内完成。我的解决方案是发送带有超时的请求。当超时触发时,我想发送另一个请求。但是,我想让前一个请求保持打开状态,并将其与新请求进行竞争。我想这样做,直到其中一个开放请求完成,结束所有开放请求的竞争。
我也愿意听取关于解决这个问题的其他方法的建议。

const timeoutLimit = 300;
const timeoutMessage = 'Response timed out';
/** Executes a request, retrying on timeouts, until it returns successfully. */
export default async function requestWithTimeout(request, count) {
const timeout = new Promise((resolve, reject) => {
setTimeout(() => reject(timeoutMessage), timeoutLimit);
});
const apiCall = new Promise((resolve, reject) => {
request
.catch((err) => reject(err))
.then((resp) => resolve(resp));
});
count += 1;
const result = await Promise.race([apiCall, timeout])
.catch((err) => {
console.log(err, count);
return (err === timeoutMessage) ? Promise.race([apiCall, requestWithTimeout(request, count)]) : err;
})
.then((val) => {
console.log('returned', count);
return val;
});
console.log(count, result);
return result;
}

下面是控制台输出的一个示例:输出指示超时和响应顺序的语句

我总是按这个顺序打印:

Response timed out 1
Response timed out 2
returned 1
returned 2
returned 3
data 1
data 2
data 3

但是我希望我的回答是这样的:

Response timed out 1
Response timed out 2
returned 1
data 1
returned 3
data 3
returned 2
data 2

我的解决方案是使用一个数组来跟踪未完成的承诺。通过这种方式,我可以打开一个请求,并将其与之前仍然挂起的请求进行竞争,这些请求在超时承诺的竞争中失败了。当其中一个等待的请求承诺被完成时,竞赛将结束。这将在每个超时期间缓慢地构建一个请求数组,直到其中一个请求得到满足。通过慢慢增加并发请求的数量,而不是在超时后丢弃它们,我希望增加服务器在响应时间不稳定的情况下满足某个请求的可能性。

const timeoutLimit = 250;
const timeoutLimitMessage = 'Response timed out, retrying';
const requestLimit = 20;
const RequestLimitMessage = 'Too many requests';
/** Executes a request, retrying on timeouts, until it returns successfully. */
export default async function requestWithTimeout(request, promises = []) {
const timeout = new Promise((resolve, reject) => {
setTimeout(() => reject(timeoutLimitMessage), timeoutLimit);
});
const apiCall = new Promise((resolve, reject) => {
request
.catch((err) => reject(err))
.then((resp) => resolve(resp));
});
promises.push(apiCall);
const result = await Promise.race([...promises, timeout])
.catch((err) => {
if (err !== timeoutLimitMessage) {
return err;
}
console.log(timeoutLimitMessage);
if (promises.length > requestLimit) {
throw new Error(RequestLimitMessage);
}
return Promise.race([...promises, requestWithTimeout(request, promises)]);
})
.then((resp) => resp);
return result;
}

相关内容

  • 没有找到相关文章

最新更新