如何使polling observable检测到未实现的承诺

时间:2017-04-25 04:48:27

标签: rxjs polling

这个可观察的每秒轮询getPromise()函数。在getPromise()函数返回3个promise后,它会停止解析它们。如何检测getPromise()函数没有解析/拒绝过去的任何承诺,比方说,2秒,并调用onError处理程序。我试过让它与timeout运营商一起工作无济于事。有什么想法吗?

Rx.Observable.interval(1000)
  .switchMap(() => Rx.Observable.fromPromise(getPromise()))
  .subscribe(onValue, onError);

function onValue(value){
  console.log('value: ', value);
}
function onError(error){
  console.log('error: ', error);
}
var getPromise = (function(){
  var counter = 3;
  return function(){
    return new Promise(function(resolve, reject){
      if(counter > 0) resolve(1);
      counter--;
    })
  }
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.3.0/Rx.js"></script>

1 个答案:

答案 0 :(得分:2)

您可以使用仅订阅第一个发出的Observable的race运算符。

你说你想在2次不活动后调用onError处理程序。这与使用switchMap相矛盾,error在从其回调中返回新的Observable时自动取消订阅。因此,您可能希望使用exhaustMap。此外,当您发出错误通知时,链取消订阅,您将永远不会收到任何其他值。这意味着您不应该以{{1​​}}发出超时或使用retry运算符自动重新订阅(但这实际上取决于您要实现的目标)。

这是您使用race()运算符的更新示例。

Rx.Observable.interval(1000)
  .switchMap(() => 
    Rx.Observable.race(
      Rx.Observable.fromPromise(getPromise()),
      Rx.Observable.timer(0, 1000).mapTo(42)
    )
  )
  .subscribe(onValue, onError);

function onValue(value){
  console.log('value: ', value);
}
function onError(error){
  console.log('error: ', error);
}
var getPromise = (function(){
  var counter = 3;
  return function(){
    return new Promise(function(resolve, reject){
      if(counter > 0) resolve(1);
      counter--;
    })
  }
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.3.0/Rx.js"></script>

编辑:在2秒钟不活动后发送单个错误通知。

Rx.Observable.interval(1000)
  .switchMap(() => Rx.Observable.fromPromise(getPromise()))
  .timeout(2000)
  .subscribe(onValue, onError);

function onValue(value){
  console.log('value: ', value);
}
function onError(error){
  console.log('error: ', error);
}
var getPromise = (function(){
  var counter = 3;
  return function(){
    return new Promise(function(resolve, reject){
      if(counter > 0) resolve(1);
      counter--;
    })
  }
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.2.0/Rx.js"></script>

5.3.0中确实存在一个错误,不是直接在timeout()运算符中,而是在调度异步操作中。 https://github.com/ReactiveX/rxjs/pull/2580

没有timeout()运算符:

Rx.Observable.interval(1000)
  .switchMap(() =>
    Rx.Observable.race(
      Rx.Observable.fromPromise(getPromise()),
      Rx.Observable.timer(0, 2000).map(function(_) {
        throw new Error('timeout');
      })
    )
  )
  .subscribe(onValue, onError);