1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
export default function newTask(def, name, mainTask, cont){ let queue = forkQueue(mainTask, end); let status = taskStatus.RUNNING; let taskResult;
function end(res, isErr){ if(!isErr){ if(res === 'cancel_task'){ status = taskStatus.CANCELLED } else if(status !== taskStatus.CANCELLED){ status = taskStatus.DONE } taskResult = res; def.resolve(res); } else { status = taskStatus.ABORTED; def.reject(res); } task.joiners.forEach(joiner => { joiner.cb(res) }) task.joiners = null; task.cont(res, isErr); }
function cancel(){ if(status === taskStatus.RUNNING){ status = taskStatus.CANCELLED; queue.cancelAll(); end('cancel_task', false); } }
const task = { name, cont, status, isRunning: () => status === taskStatus.RUNNING, isCancelled: () => status === taskStatus.CANCELLED || (status === taskStatus.RUNNING && mainTask.status === taskStatus.CANCELLED), isAborted: () => status === taskStatus.ABORTED, result: () => taskResult, cancel, queue, end, joiners: [], toPromise: () => def.promise } return task }
function forkQueue(mainTask, end){ let queue = []; let result; let completed = false;
addTask(mainTask); function addTask(task){ queue.push(task); task.cont = (res, isErr) => { if(completed){ return } remove(queue, task) if(isErr){ cancelAll(); end(res, isErr); } else { if(task === mainTask){ result = res } if(!queue.length){ completed = true; end(result, false); } } } }
function cancelAll(){ if(completed){ return } completed = true; queue.forEach(task => { task.cont = noop; task.cancel(); }) queue = [] } return { addTask, cancelAll } }
|