[英]Passing a non-standard Scheduler to an operator
Let's say that I want to pass a Scheduler to an RxJS operator that makes it emit notifications every 5 seconds. 假设我想将调度程序传递给RxJS运算符,使其每5秒发出一次通知。 Of course, this is very easy to do by just using
interval
or other existing operators. 当然,仅使用
interval
或其他现有运算符就可以轻松完成。 But if I really want to use a scheduler to accomplish that, how would I go about it? 但是,如果我真的想使用调度程序来完成它,我该怎么做呢?
My first thought is to subclass Rx.Scheduler.default
. 我的第一个想法是
Rx.Scheduler.default
。 Would that be the way to go? 这会是要走的路吗? And if so, how could that subclass look?
如果是这样,该子类怎么样? Again, I understand that this is a complicated way to accomplish something that's easy using operators, but I am just curious about custom schedulers.
同样,我理解这是一种复杂的方法来完成使用运算符很容易的东西,但我只是对自定义调度程序感到好奇。
Operations should always be independent of the Schedulers that are used to implement them. 操作应始终独立于用于实现它们的调度程序。 Schedulers only know about one thing, time.
调度员只知道一件事,时间。 Every scheduler is specifically built to deal with its own notion of time.
每个调度程序都专门用于处理自己的时间概念。 They are expressly not built to handle specific operators since that would be a conflation of concerns.
它们明确地不是为处理特定运营商而构建的,因为这将是一个关注点的混合。
So for your stated goal of creating a recurring task, I wouldn't recommend trying to actually create your own scheduler, it simply isn't needed. 因此,对于您创建定期任务的既定目标,我不建议您尝试实际创建自己的调度程序,而根本不需要。 Schedulers come with an interface that already supports this.
调度程序带有一个已经支持此功能的接口。
You can use either the schedulePeriodic
or the scheduleRecursiveFuture
to accomplish this. 您可以使用
schedulePeriodic
或scheduleRecursiveFuture
来完成此任务。
//Using periodic
Rx.Observable.interval = function(period, scheduler) {
return Rx.Observable.create(function(observer) {
return scheduler.schedulePeriodic(0, period, function(count) {
observer.onNext(count);
return count + 1;
});
});
};
//Using scheduleRecursive
Rx.Observable.interval = function(period, scheduler) {
return Rx.Observable.create(function(observer) {
return scheduler.scheduleRecursiveFuture(0, period, function(count, self) {
observer.onNext(count);
self(period, count + 1);
});
});
};
Reference 1 , Reference 2 ; 参考文献1 , 参考文献2 ;
The former should be easier to wrap your head around, essentially it is just scheduling something to occur repeatedly spaced in time based on the period parameter. 前者应该更容易包围你的头,基本上它只是根据周期参数安排在时间上重复间隔发生的事情。
The latter is usually a little more difficult to explain, but essentially you are scheduling a task and then sometime during the execution of that task you are rescheduling it (which is what the self
parameter) is doing. 后者通常有点难以解释,但实际上你是在安排一个任务,然后在执行该任务的某个时候你重新安排它(这是
self
参数)正在做的事情。 This allows you do get the same effect using the period parameter. 这允许您使用period参数获得相同的效果。
The timing of this work is all directly affected by which scheduler you decide to pass into the operator. 这项工作的时间直接受到您决定传入运营商的调度程序的影响。 For instance, if you pass in the
default
it will try to use the best method for an asynchronous completion, whether that be setTimeout
, setInterval
or some other thing I can't remember. 例如,如果传入
default
,它将尝试使用最佳方法进行异步完成,无论是setTimeout
, setInterval
还是其他一些我不记得的事情。 If you pass in a TestScheduler
or a HistoricalScheduler
this actually won't do anything until you increment each of their respective clocks, but doing so gives fine grained control over how time flows. 如果传入
TestScheduler
或HistoricalScheduler
,在递增每个时钟之前实际上不会执行任何操作,但这样做可以对时间流量进行精细控制。
tl;dr Only implement new Scheduler
s if you have some new overall notion of time to express, otherwise use the existing API to do work on whatever Scheduler
best fits how you want time to pass. tl; dr如果你有一些新的整体时间概念,那么只实现新的
Scheduler
,否则使用现有的API来做任何最适合你想要时间的Scheduler
。
Plainly: No. Most likely you can get done what you need done with an existing operator. 显而易见:不是。很可能你可以完成现有操作员所需的工作。 Something like
buffer
, window
, sample
, etc. Scheduler development is not completely straightforward. 像
buffer
, window
, sample
等。调度程序开发并不是完全简单的。
If you want to implement your own Scheduler, in RxJS 4, you'd subclass Rx.Scheduler
, then override each schedule method: schedule
, scheduleFuture
, schedulePeriodic
, scheduleRecursive
, scheduleRecursiveFuture
... You'd also likely want to override now
to return something relevant to your schedule. 如果你想实现自己的调度程序,在RxJS 4中,你是子类
Rx.Scheduler
,然后覆盖每个调度方法: schedule
, scheduleFuture
, schedulePeriodic
, scheduleRecursive
, scheduleRecursiveFuture
......你也可能想要覆盖now
返回与你的日程安排相关的东西
Here is an example of a custom scheduler that uses button clicks inside of real time 以下是使用实时内部按钮单击的自定义调度程序示例
/**
NOTE: This is REALLY fast example. There is a lot that goes into implementing a
Scheduler in RxJS, for example what would `now()` do in the scheduler below? It's also missing a number of scheduling methods.
*/
class ButtonScheduler extends Rx.Scheduler {
/**
@param {string} the selector for the button (ex "#myButton")
*/
constructor(selector) {
super();
this.button = document.querySelector(selector);
}
schedule(state, action) {
const handler = (e) => {
action(state);
};
const button = this.button;
// next click the action will fire
button.addEventListener('click', handler);
return {
dispose() {
// ... unless you dispose of it
button.removeEventListener('click', handler);
}
};
}
// Observable.interval uses schedulePeriodic
schedulePeriodic(state, interval, action) {
const button = this.button;
let i = 0;
const handler = (e) => {
const count = i++;
if(count > 0 && count % interval === 0) {
state = action(state);
}
};
// next click the action will fire
button.addEventListener('click', handler);
return {
dispose() {
// ... unless you dispose of it
button.removeEventListener('click', handler);
}
};
}
}
Rx.Observable.interval(1, new ButtonScheduler('#go'))
.subscribe(x => {
const output = document.querySelector('#output');
output.innerText += x + '\n';
});
Scheduling changed again in RxJS 5 , since that version was rewritten from the ground up. RxJS 5中的调度再次发生变化,因为该版本是从头开始重写的。
In RxJS5, you can create any object that adheres to the following interface: 在RxJS5中,您可以创建任何符合以下界面的对象:
interface Scheduler {
now(): number
schedule(action: function, delay: number = 0, state?: any): Subscription
}
Where Subscription
is just any object with an unsubscribe
function (same as dispose
, really) Subscription
只是具有unsubscribe
功能的任何对象(与dispose
相同,真的)
Once again, though, I don't advise creating a scheduler unless it's completely necessary. 但是,我再次建议不要创建一个调度程序,除非它是完全必要的。
I really hope that helps answer your question. 我真的希望这有助于回答你的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.