【发布时间】:2018-09-29 16:43:50
【问题描述】:
使用p-queue,我可以限制我在一段时间内启动一些异步操作(例如,API 请求)的次数,以及一次可以运行多少个这些异步操作。
效果很好,但我觉得我应该可以用RxJS 做同样的事情。我很难弄清楚如何做到这一点。我对 RxJS 还是很陌生,我还没有找到任何可以做我想做的事情的例子。
我看到buffer 和throttleTime 等运算符,这些似乎是可行的方法,但我很难将所有这些信息放在一起。
我将如何复制 p-queue 的配置:
{
concurrency: 2 /* at a time */
, intervalCap: 10 /* per every… */
, interval: ( 15 /* seconds */ * 1000 /* milliseconds */)
, carryoverConcurrencyCount: true
}
…使用RxJS?
RxJS 解决方案应该:
- 当队列为空时立即允许通过值(即立即开始一个新的时间间隔,而不是等待某个时间间隔取决于队列最后一次非空的时间)
- 提供与p-queue 的
carryoverConcurrencyCount相同的功能:“……任务必须在给定的时间间隔内完成,否则将结转到下一个时间间隔计数。”
使用p-queue的完整示例:
// Queue/Concurrency-limit requests
const PQueue = require('p-queue') ;
const requestQueue = new PQueue({
concurrency: 2 /* at a time */
, intervalCap: 10 /* per every… */
, interval: ( 15 /* seconds */ * 1000 /* milliseconds */)
, carryoverConcurrencyCount: true
}) ;
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}
const queuePromises = (
[...(Array(20)).keys()]
.map(number => requestQueue.add(() => new Promise(
(resolve, reject) => setTimeout(() => resolve(number), getRandomInt(0, /* up to */ 250) /* milliseconds */))
))
) ;
queuePromises.forEach(queuePromise => queuePromise.then(
number => console.log(number, 'resolved')
, error => console.error('Individual Promise error', error)
)) ;
Promise.all(queuePromises).then(
numbers => console.log('all are resolved', ...numbers)
, error => console.error('All Promises error', error)
) ;
【问题讨论】:
标签: javascript promise rxjs queue observable