-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4dc34b3
commit 9a040fa
Showing
7 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Scheduler, Subscription } from "rxjs"; | ||
import { cancel, later, run } from "@ember/runloop"; | ||
|
||
class RunLoopAction extends Subscription { | ||
constructor(scheduler, work) { | ||
super(() => cancel(this.timer)); | ||
|
||
this.scheduler = scheduler; | ||
this.work = work; | ||
} | ||
|
||
schedule(state, delay) { | ||
if (delay) { | ||
this.timer = later(this, this.work, state, delay); | ||
} else { | ||
run(this, this.work, state); | ||
} | ||
|
||
return this; | ||
} | ||
} | ||
|
||
export default new Scheduler(RunLoopAction); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Run Loop Scheduler | ||
|
||
RxJS has the concept of a [Scheduler][rxjs-scheduler], which is can use to queue work that should happen sometime in the future. Many Observables or Operators that deal with "time" can take accept a Scheduler as an argument if you need to customize how this work is planned. | ||
|
||
Ember also has a means for scheduling tasks in the future; the [Run Loop][run-loop]. In order to schedule events from RxJS into the Run Loop, you can leverage the scheduler provided by `ember-rx`. | ||
|
||
```javascript | ||
import { scheduler as runLoopScheduler } from "ember-rx"; | ||
import { interval } from "rxjs"; | ||
|
||
const observable = interval(1000, runLoopScheduler); | ||
const subscription = observable.subscribe(val => { | ||
// Each emission from `interval` will be scheduled into a Run Loop | ||
console.log(value); | ||
}); | ||
|
||
// Unsubscribing will cancel any scheduled-but-not-run Run Loops | ||
subscription.unsubscribe(); | ||
``` | ||
|
||
[rxjs-scheduler]: https://rxjs.dev/guide/scheduler | ||
[run-loop]: https://guides.emberjs.com/release/applications/run-loop/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { module, test } from "qunit"; | ||
import td from "testdouble"; | ||
import { getSettledState, settled } from "@ember/test-helpers"; | ||
import { defer } from "rsvp"; | ||
import { from } from "rxjs"; | ||
import { delay } from "rxjs/operators"; | ||
import { scheduler as runloopScheduler } from "ember-rx"; | ||
|
||
module("Unit | Scheduler", function() { | ||
test("it schedules immediate work using the Runloop", async function(assert) { | ||
const deferred = defer(); | ||
const observable = from(deferred.promise, runloopScheduler); | ||
const observer = td.function("observer"); | ||
observable.subscribe(observer); | ||
|
||
deferred.resolve("resolution"); | ||
|
||
const state = getSettledState(); | ||
|
||
assert.ok(state.hasRunLoop, 'A run loop was started with the "work"'); | ||
|
||
assert.verify( | ||
observer("resolution"), | ||
{ times: 0 }, | ||
"Observer not yet called" | ||
); | ||
|
||
await settled(); | ||
|
||
assert.verify( | ||
observer("resolution"), | ||
{ times: 1 }, | ||
"Observer called once the runloop has settled" | ||
); | ||
}); | ||
|
||
module("delayed work", function() { | ||
test("it schedules later work using the Runloop", async function(assert) { | ||
const observable = from([1]).pipe(delay(10, runloopScheduler)); | ||
const observer = td.function("observer"); | ||
observable.subscribe(observer); | ||
|
||
const state = getSettledState(); | ||
|
||
assert.ok( | ||
state.hasPendingTimers, | ||
"Work scheduled for later in the runloop" | ||
); | ||
|
||
await settled(); | ||
|
||
assert.verify(observer(1), "Eventually called with the scheduled work"); | ||
}); | ||
|
||
test("it can cancel a scheduled runloop", async function(assert) { | ||
const observable = from([1]).pipe(delay(10, runloopScheduler)); | ||
const subscription = observable.subscribe(td.function("observer")); | ||
|
||
subscription.unsubscribe(); | ||
|
||
const state = getSettledState(); | ||
|
||
assert.notOk(state.hasPendingTimers, "Scheduled work has been cancelled"); | ||
}); | ||
}); | ||
}); |