To schedule events one-after another. To play lazy animations in order, correlated with their position on the page.
Scheduler
- task scheduler. Collect tasks and execute them withstepDelay
between in thepriority
order.stepDelay
- delay between two events[reverse]
- reverses the queue[source]
- priority calculation function[withSideEffect]
- indicates that Scheduler has side effects, and enabled auto update(re-render) on task execution. Affects performance.[observe]
- cache buster property. Scheduler sorts queue only on element change, in case of usingsource
you might need "inform"[noInitialDelay]
- remove delay from the first task.[disabled]
- disables ticking it to resort queue.
import {Scheduler} from 'react-queue';
<Scheduler stepDelay={1000} >
{channel => .... }
</Scheduler>
// use source to create priority based on element position on the page
<Scheduler stepDelay={1000} source={ ({ref}) => ref.getBoundingClientRect().top} />
channel
also provides channel.reset()
function, to clear all executed
bits, and start everything from the scratch.
Queue
- queued event. It just got executed, nothing more. "When", in "when order" - that is the question.channel
- channel acquired from Schedulercallback
- callback to execute. In case if callback will return a number, or a promise resolving to number, it would be used to shift delay to the next step.priority
- pririty in queue, where 0-s should be executed before 1-s.- [
shift
] - sub priority change.shift={-1}
will swap this task with previous sibling. - [
disabled
] - holds queue execution (sets priority to Infitity). next tick will be moved by {number}ms. In case of just Promise - next tick will wait to for promise to be resolved. - [
children
] - any DOM node, Queue will pass asref
into scheduler'ssource
import {Scheduler, Queue} from 'react-queue';
<Scheduler stepDelay={1000} >
{channel =>
<Queue channel={channel} priority={1} callback={doSomething} />
// this one will report `ref` to the scheduler
<Queue channel={channel} callback={doSomething}>
<div>42</div>
</Queue>
<Queue channel={channel} callback={() => this.setState({x: 1})}>
<div style={{position: 'absolute', top: 50}}> 1 {x == 1 && "selected!!"}</div>
</Queue>
<Queue channel={channel} callback={() => this.setState({x: 2})}>
<div style={{position: 'absolute', top: 10}}> 2 {x == 2 && "selected!!"}</div>
</Queue>
<Queue channel={channel} callback={() => this.setState({x: 3})}>
<div style={{position: 'absolute', top: 100}}> 3 {x == 3 && "selected!!"}</div>
</Queue>
}
</Scheduler>
FlattenPriorityGroup
- "flattens" all priority changes inside. Could help manage nested tasks.channel
- channel acquired from Scheduler- [
children
] - render function - [
priority
] - task priority. Would be set for all nested tasks. - [
shift
] - sub priority change.shift={-1}
will swap this task with previous sibling. - [
disabled
] - holds queue execution (sets priority to Infitity).
In the next example executing order would be - 2, 1, 4, 3.
<Scheduler stepDelay={1000} >
{channel => (
<React.Fragment>
<FlattenPriorityGroup channel={channel}>
{ pchannel => [
<Promised priority={1}>1</Promised>,
<Promised priority={0}>2</Promised>
]}
</FlattenPriorityGroup>
<FlattenPriorityGroup channel={channel}>
{ pchannel => [
<Promised priority={1}>3</Promised>,
<Promised priority={0}>4</Promised>
]}
</FlattenPriorityGroup>
</React.Fragment>
)}
</Scheduler>
Promised
- promised event. Once it started it should alldone
when it's done. This is a more complex form of queue, with much stronger feedback.channel
- channel acquired from Scheduler- [
children
] - render function - [
autoexecuted
] - auto "done" the promised. boolean or number. If number - would be used to shift next step. - [
priority
] - task priority. Lower goes first - [
shift
] - sub priority change.shift={-1}
will swap this task with previous sibling. - [
disabled
] - holds queue execution (sets priority to Infitity).
import {Scheduler, Promised} from 'react-queue';
import {Trigger} from 'recondition';
<Scheduler stepDelay={1000} >
{channel =>
<Promised channel={channel} priority={1}>
{({executed, active, done, forwardRed}) => (
<div ref={forwardRed}>
{executed && "task is done"}
{active && "task is running"}
// don't call anything in render
<Trigger when={active} then={() => done(42/* make next step by 42ms later*/)}/>
</div>
)
</Promised>
}
</Scheduler>
// this code has the same behavior
<Scheduler stepDelay={1000} >
{channel =>
<Promised channel={channel} priority={1} autoexecuted={42}>
{({executed, active, done, forwardRed}) => (
<div ref={forwardRed}>
{executed && "task is done"}
{active && "task is running"}
</div>
)
</Promised>
}
</Scheduler>
For example - animation - it will execute one Promised
after another, and triggering waterfall animation.
import {Scheduler, Promised} from 'react-queue';
import {Trigger} from 'recondition';
<Scheduler stepDelay={300} >
{channel =>
<Promised channel={channel} autoexecuted>
{({executed, active, fired}) => (<div style={styles[executed||active ? styleA : styleB}>Line1</div>)}
</Promised>
<Promised channel={channel} autoexecuted>
{({executed, active, fired}) => (<div style={styles[executed||active ? styleA : styleB}>Line2</div>)}
</Promised>
<Promised channel={channel} autoexecuted>
{({executed, active, fired}) => (<div style={styles[executed||active ? styleA : styleB}>Line3</div>)}
</Promised>
<Promised channel={channel} autoexecuted>
{({executed, active, fired}) => (<div style={styles[executed||active ? styleA : styleB}>Line4</div>)}
</Promised>
}
</Scheduler>
react-remock + react-queue - simple and complex example - "jquery like" image lazy loading with queued execution. react-visibility-sensor + react-queue - animate element appearance based on visibility check.
MIT