我正在构建一个交易机器人,有时需要多次调用Exchange的API(例如,重新连接后刷新N个图表)。我想让这些调用有时间间隔,这样我就不会淹没API(我仍然不想放弃我需要进行的任何调用,因此去抖动/节流不是我想要的) 。像这样:
来源:[更新图表1,更新图表2,...,更新图表N]
可观察到:[更新图表1->等待1秒->更新图表2->等待1秒-> ...->更新图表N]
我希望这个观察结果能在N-1秒内完成。
如何构建这样的Observable? (我正在使用rxjs ^ 6.3.3)
注意:我正在研究使用callAPI Subject将所有对API的调用包装起来并以某种方式延迟它们的想法,但是我也无法弄清楚。
谢谢。-
更新:好的,我最终使用了Bottleneck,就像这样:
const limiter = new Bottleneck({
minTime: 1000
})
然后:chartsToReset.map(async (chart) => await limiter.schedule(() => exchangeAPI.updateChart(chart)))
答案 0 :(得分:0)
您可以使用具有Promise + setTimeout和递归函数的函数(类似):
var runQueries = function(source) {
if (source.length > 0) {
runQuery(source[0]).then(() => runQueries(source.slice(1));
} else {
console.log('done!')
}
}
// this is just pseudo code...
var runQuery = function(item) {
//var promise = new Promise
//run code
// setTimeout for 1000 to resolve promise
// return promise
}
修改
如果迭代函数对数组无损,并且您可以使用属性queryRunning和查询(或其他方法)(我没有使用rxjs,因此您必须对该格式稍作修改) ):
var next = function(query) {
// queries and queryRunning are properties on the thing doing these calls
queries.push(query);
if (!queryRunning) {
runQueries();
}
}
var runQueries = function() {
if (queries.length > 0) {
queryRunning = true;
runQuery(queries.shift()).then(() => runQueries();
} else {
queryRunning = false;
console.log('done!')
}
}
// this is just pseudo code...
var runQuery = function(query) {
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('complete');
}, 1000);
});
//run code to handle query
return promise1;
}
答案 1 :(得分:0)
您可能希望沿着这些思路结合interval
运算符来查看mergeMap
RxJS创建函数
const updates = ['chart1', 'chart2', 'chart3'];
// this function simulates fetching of data for the chart
function getUpdatedChartData(chartName: string) {
return of({chart: chartName, data: [chartName + ' 1', chartName + ' 2', chartName + ' 3']}).pipe(
delay(Math.random() * 2000)
)
}
const theObservableIWantToBuild = interval(1000).pipe(
take(updates.length),
mergeMap(i => getUpdatedChartData(updates[i]).pipe(
tap(chartData => {
console.log(JSON.stringify(chartData, null, 3))
// do something with chart data)
}),
map(() => updates[i])
)),
)
您可能会看到,在模拟函数getUpdatedChartData
中,我添加了一个延迟,只是为了使其更加真实。
作为一般规则,在相对有限的情况下,需要受试者。每当您认为需要使用Subject时,请问自己是否存在不存在需要简单使用运算符的等效解决方案。