1.0.6 • Published 2 years ago
nv-task-serial v1.0.6
nv-task-serial
- nv-task-serial is for serialized-async-tasks
- its behavior just like the nodejs timer-list
- its a linked-list
- with more APIS ,such as:
- get prev-task-rslt
- dynamically push task
- pause/continue task
- skip/stop task
- each-action with event-target
install
- npm install nv-task-serial
usage
var {TaskList} = require("nv-task-serial");
var tl = new TaskList((tail_resolve,tail_reject,history_tasks)=>{/*...*/})
tl.regis_resolve((e)=>{console.log("resolve happened: ",e.data)})
tl.regis_reject((e)=>{console.log("reject happened: ",e.data)})
tl.launch();
tl.push((resolve,reject,self)=>{/*....*/}) //dynamically add task
.....
tl.push((resolve,reject,self)=>{/*....*/}) //dynamically add task
....
tl.then((result_when_reach_tail)=>{/*...*/})
example
init
//new TaskList(handler_when_reach_tail)
//handler_when_reach_tail: (resolve,reject,history_tasks)=>{}
var tl = new TaskList((rs,rj,tasks)=>{rs(tasks)})
regis event-handler
tl.regis_resolve((e)=>{console.log("resolve happened: ",e.data)})
tl.regis_reject((e)=>{console.log("reject happened: ",e.data)})
/*
e.data is a Task with the following methods
tsk.disconn tsk.fsibs tsk.gen_fsibs
tsk.gen_psibs tsk.index_of tsk.is_head
tsk.is_lonely tsk.is_tail tsk.list
tsk.next tsk.prev tsk.psibs
tsk.exception tsk.exec
tsk.final tsk.id tsk.insert_after
tsk.insert_before tsk.is_impossible tsk.is_paused
tsk.is_pending tsk.is_rejected tsk.is_resolved
tsk.is_settled tsk.is_skipped tsk.is_stopped
tsk.rslt tsk.state
*/
launch
tl.launch();
push
tl.push((resolve,reject,self)=>{/*.....*/})
/*
self is the internal-node ,it is a Task
using self.prev CAN get the previous task
.rslt can get the resolved
.exception can get the rejected
.final can get resolved/rejected ignore-error(by-default)
*/
//for test , we prepare a random-task-creater
/*
// create task functions for test
function creat_random_tsk_template(name,max_timeout=5000,fail_ratio=0.7) {
function _tsk(rs,rj,self) {
let delay = Math.random() * max_timeout;
setTimeout(
()=>{
//optional this is for paused/skipped optimize
if(!self.is_pending()) {return}
//------task
let p = self.prev; //get rslt from prev Task
if(self.is_head()) {
console.log("after " + delay + " seconds->"+name+" triggered");
rs(0);
} else {
if(delay>max_timeout*fail_ratio){
console.log("after " + delay + " seconds->"+name+" fail");
rj(p.final + 1) //final used when ignore_error ,means rslt-or-exception
} else {
console.log("after " + delay + " seconds->"+name+" succ");
rs(p.final + 1)
}
}
//------task
},
delay
)
}
Object.defineProperty(_tsk,"name",{value:name})
return(_tsk)
}
*/
var tsk0 = creat_random_tsk_template('tsk0')
tl.push(tsk0)
var tsk1 = creat_random_tsk_template('tsk1')
tl.push(tsk1)
tl.push(creat_random_tsk_template('tsk2'))
tl.push(creat_random_tsk_template('tsk3'))
tl.push(creat_random_tsk_template('tsk4'))
tl.push(creat_random_tsk_template('tsk5'))
/*
> after 3004.188365079519 seconds->tsk0 triggered
resolve happened: { promise: Promise { 0 }, task: 'tsk0' }
> after 3683.875271987046 seconds->tsk1 fail
reject happened: { promise: Promise { <rejected> 1 }, task: 'tsk1' }
......
*/
history
//by default, history_size is 1
//which means 1-history-task + current-task
//only one task before current-task is keeped
//when task-after-current finished, the TaskList head will auto-shift
> tl.history_size
1
>
> tl.history
[ { promise: Promise { <rejected> 6 }, task: 'tsk4' } ]
>
> tl.curr
{ promise: Promise { <rejected> 7 }, task: 'tsk5' }
>
> Array.from(tl) //history + curr
[
{ promise: Promise { <rejected> 6 }, task: 'tsk4' },
{ promise: Promise { <rejected> 7 }, task: 'tsk5' }
]
>
other event-handler
tl.regis_pause((e)=>{console.log("pause happened: ",e.data)})
tl.regis_continue((e)=>{console.log("continue happened: ",e.data)})
tl.regis_skip((e)=>{console.log("skip happened: ",e.data)})
tl.regis_stop((e)=>{console.log("stop happened: ",e.data)})
tl.push(creat_random_tsk_template('tsk6',50000))
tl.push(creat_random_tsk_template('tsk7',40000))
tl.push(creat_random_tsk_template('tsk8',30000))
tl.push(creat_random_tsk_template('tsk9',20000))
tl.push(creat_random_tsk_template('tsk10',10000))
pause
//pause can NOT real-stop the current Task
//because you can NOT control the-bottom-layer ,such as http-request
//but it can stop the continuous tasks
//and rerun the "paused"-task when continue
// if you want to REAL-pause and avoid dupilicate-rerun the-paused-task
// you can insert `if(!self.is_pending()) {return}` at your task-function (rs,rj,self)=>{/*...*/}
// see exzample creat_random_tsk_template at [&A]
tl.pause()
/*
pause happened: {
promise: Promise { <pending>, [Symbol(paused)]: true },
task: 'tsk6'
}
> Array.from(tl)
[
{ promise: Promise { <rejected> 5 }, task: 'tsk5' },
{
promise: Promise { <pending>, [Symbol(paused)]: true },
task: 'tsk6'
},
{ promise: Promise { <pending> }, task: 'tsk7' },
{ promise: Promise { <pending> }, task: 'tsk8' },
{ promise: Promise { <pending> }, task: 'tsk9' },
{ promise: Promise { <pending> }, task: 'tsk10' }
]
> after 20943.462337496952 seconds->tsk6 fail //cant real-stop ,just ignore
*/
continue
tl.continue()
/*
> after 41625.25588356653 seconds->tsk6 fail
reject happened: { promise: Promise { <rejected> 6 }, task: 'tsk6' }
after 2837.002839417808 seconds->tsk7 succ
resolve happened: { promise: Promise { 7 }, task: 'tsk7' }
> after 29714.166746318606 seconds->tsk8 fail
reject happened: { promise: Promise { <rejected> 8 }, task: 'tsk8' }
after 8094.91522823687 seconds->tsk9 succ
resolve happened: { promise: Promise { 9 }, task: 'tsk9' }
after 10.748628205963229 seconds->tsk10 succ
resolve happened: { promise: Promise { 10 }, task: 'tsk10' }
*/
skip
tl.push(creat_random_tsk_template('longtime-task',1000000))
tl.push(creat_random_tsk_template('longtime-task',1000000))
tl.push(creat_random_tsk_template('longtime-task',1000000))
tl.push(creat_random_tsk_template('longtime-task',1000000))
tl.push(creat_random_tsk_template('tsk11',10000))
tl.push(creat_random_tsk_template('tsk12',10000))
/*
> Array.from(tl)
[
{ promise: Promise { <rejected> 10 }, task: 'tsk10' },
{ promise: Promise { <pending> }, task: 'longtime-task' },
{ promise: Promise { <pending> }, task: 'longtime-task' },
{ promise: Promise { <pending> }, task: 'longtime-task' },
{ promise: Promise { <pending> }, task: 'longtime-task' },
{ promise: Promise { <pending> }, task: 'tsk11' }
{ promise: Promise { <pending> }, task: 'tsk12' }
]
>
*/
//skip the 4 longtime-tasks
tl.skip(4)
/*
> tl.skip(4)
skip happened: {
promise: Promise { , [Symbol(skipped)]: true },
task: 'longtime-task'
}
skip happened: {
promise: Promise { , [Symbol(skipped)]: true },
task: 'longtime-task'
}
skip happened: {
promise: Promise { , [Symbol(skipped)]: true },
task: 'longtime-task'
}
skip happened: {
promise: Promise { , [Symbol(skipped)]: true },
task: 'longtime-task'
}
> Array.from(tl)
[
{
promise: Promise { , [Symbol(skipped)]: true },
task: 'longtime-task'
},
{ promise: Promise { <pending> }, task: 'tsk11' },
{ promise: Promise { <pending> }, task: 'tsk12' }
]
> after 7258.038279573549 seconds->tsk11 fail
reject happened: { promise: Promise { <rejected> 11 }, task: 'tsk11' }
> after 7380.624658753325 seconds->tsk12 fail
reject happened: { promise: Promise { <rejected> 12 }, task: 'tsk12' }
>
*/
stop
tl.push(creat_random_tsk_template('tsk13',50000))
tl.push(creat_random_tsk_template('tsk14',50000))
tl.push(creat_random_tsk_template('tsk15',50000))
tl.push(creat_random_tsk_template('tsk16',50000))
//stopped task can NOT continue, must reset and re-launch
tl.stop()
/*
> tl.stop()
stop happened: { promise: Promise { <rejected> }, task: 'tsk13' }
undefined
>
> Array.from(tl)
[
{ promise: Promise { <rejected> 12 }, task: 'tsk12' },
{ promise: Promise { , [Symbol(stopped)]: true }, task: 'tsk13' },
{
promise: Promise { <pending>, [Symbol(impossible)]: true },
task: 'tsk14'
},
{
promise: Promise { <pending>, [Symbol(impossible)]: true },
task: 'tsk15'
},
{
promise: Promise { <pending>, [Symbol(impossible)]: true },
task: 'tsk16'
}
]
>
*/
reset
tl.reset()
/*
> Array.from(tl)
[
{ promise: Promise { <pending> }, task: 'tsk12' },
{ promise: Promise { <pending> }, task: 'tsk13' },
{ promise: Promise { <pending> }, task: 'tsk14' },
{ promise: Promise { <pending> }, task: 'tsk15' },
{ promise: Promise { <pending> }, task: 'tsk16' }
]
>
*/
tl.launch()
/*
> after 8151.528852357599 seconds->tsk12 triggered
resolve happened: { promise: Promise { 0 }, task: 'tsk12' }
> after 42358.18225767119 seconds->tsk13 fail
reject happened: { promise: Promise { <rejected> 1 }, task: 'tsk13' }
> after 23731.270105362368 seconds->tsk14 succ
resolve happened: { promise: Promise { 2 }, task: 'tsk14' }
> after 11129.58550558505 seconds->tsk15 succ
resolve happened: { promise: Promise { 3 }, task: 'tsk15' }
> after 5151.571964477531 seconds->tsk16 succ
resolve happened: { promise: Promise { 4 }, task: 'tsk16' }
>
*/
finish_handler
> tl.then(r=>console.log(r))
Promise { <pending> }
> [
{ promise: Promise { 3 }, task: 'tsk15' },
{ promise: Promise { 4 }, task: 'tsk16' }
]
>
METHODS
TaskList
tl.append tl.get_item tl.head
tl.index_of tl.insert_at tl.is_empty
tl.length tl.prepend tl.rm_at
tl.tail tl.to_array
tl.catch tl.cexec tl.constructor
tl.continue tl.curr tl.et
tl.finally tl.history tl.history_size
tl.is_in_executing tl.launch tl.max_history_size
tl.pause tl.push tl.regis_continue
tl.regis_pause tl.regis_reject tl.regis_resolve
tl.regis_skip tl.regis_stop tl.reset
tl.skip tl.stop tl.then
tl[Symbol.iterator]
Task(self)
t.disconn t.fsibs t.gen_fsibs t.gen_psibs
t.index_of t.is_head t.is_lonely t.is_tail
t.list t.next t.prev t.psibs
t.constructor t.exception t.exec t.final
t.id t.insert_after t.insert_before t.is_impossible
t.is_paused t.is_pending t.is_rejected t.is_resolved
t.is_settled t.is_skipped t.is_stopped t.rslt
t.state
APIS
- EVENT_DICT,
- TASK_ERROR_DICT,
- TaskList((resolve,reject,history_tasks)=>{/..../}),
LICENSE
- ISC