在rxjs管道中实现循环逻辑

在rxjs管道中实现循环逻辑,rxjs,Rxjs,我有一个类,QueueManager,它管理一些队列 QueueManager提供3个API deleteQueue(queueName:string):可观察 createQueue(queueName:string):可观察 listQueues():可观察的:可观察的` deleteQueue是一个fire-and-forget API,在这个意义上说,它在完成工作并删除队列后不会返回任何信号。同时,如果已经存在同名队列,则createQueue将失败 listQueues()返回队列

我有一个类,QueueManager,它管理一些队列

QueueManager提供3个API

  • deleteQueue(queueName:string):可观察
  • createQueue(queueName:string):可观察
  • listQueues():可观察的
    :可观察的`
deleteQueue
是一个fire-and-forget API,在这个意义上说,它在完成工作并删除队列后不会返回任何信号。同时,如果已经存在同名队列,则
createQueue
将失败

listQueues()
返回队列管理器管理的队列的名称

我需要创建一段逻辑来删除队列并重新创建它。所以我的想法是做一些

deleteQueue(queueName).pipe(
  map(() => [queueName]),
  expand(queuesToDelete => {
    return listQueues().pipe(delay(100))  // 100 ms of delay between checks
  }),
  filter(queues => !queues.includes(queueName)),
  first() // to close the stream when the queue to cancel is not present any more in the list
)
  • 调用
    deleteQueue(queueName)
    方法
  • 启动一个调用
    listQueues
    方法的循环,直到返回的结果显示
    queueName
    不再存在
  • 调用
    createQueue(queueName)
我认为我不能使用
retry
repeat
操作符,因为它们重新订阅源代码,在这种情况下意味着多次发出
deleteQueue
命令,这是我需要避免的

所以我想做的是

deleteQueue(queueName).pipe(
  map(() => [queueName]),
  expand(queuesToDelete => {
    return listQueues().pipe(delay(100))  // 100 ms of delay between checks
  }),
  filter(queues => !queues.includes(queueName)),
  first() // to close the stream when the queue to cancel is not present any more in the list
)
这种逻辑似乎确实有效,但在我看来有点笨拙。有没有更优雅的方法来解决这个问题呢?

需要行
映射(()=>[queueName])
,因为
扩展
也会从它的源可观测值中发出值,但我不认为这一点很明显

您可以使用
repeat
,只需订阅
listQueues
observable,而不是
deleteQueue

我还将延迟放在了
列表队列
之前,否则您将等待发出一个已经从API返回的值

const{timer,concat,operators}=rxjs;
const{tap,delay,filter,first,mapTo,concatMap,repeat}=运算符;
常量queueName='A';
constdeletequeue=(queueName)=>计时器(100);
const listQueues=()=>concat(
计时器(1000)。管道(映射到(['A','B']),
计时器(1000)。管道(映射到(['A','B']),
计时器(1000).pipe(映射到(['B']),
);
const source=deleteQueue(queueName).pipe(
轻触(()=>console.log('queue deleted'),
concatMap(()=>
计时器(100)。管道(
concatMap(列表队列),
点击(queues=>console.log('queues',queues)),
重复(),
筛选器(队列=>!队列。包括(队列名称)),
第一()
)
)
);
订阅(x=>console.log('next',x),e=>console.error(e),()=>console.log('complete')