미디어위키:Gadget-Tasker.js: 두 판 사이의 차이
imported>Senouis (hsl0님 요청) |
imported>Hsl0 (Hsl0의 276205판 편집을 되돌림) |
||
(사용자 2명의 중간 판 10개는 보이지 않습니다) | |||
3번째 줄: | 3번째 줄: | ||
* 1. renderer: DOM 요소를 만들거나 수정합니다. | * 1. renderer: DOM 요소를 만들거나 수정합니다. | ||
* 2. handler: 이벤트를 예약합니다. | * 2. handler: 이벤트를 예약합니다. | ||
* 3. trigger: | * 3. trigger: 사용자 개입 없이 바로 시작되는 작업입니다. | ||
**/ | **/ | ||
var TASKS = Symbol('tasks_queue'); | var TASKS = Symbol('tasks_queue'); | ||
var WAITING = Symbol('waiting_queue'); | var WAITING = Symbol('waiting_queue'); | ||
var ERRORS = Symbol('errors'); | |||
function capture(queue) { | |||
var arr = Array.from(queue); | |||
queue.clear(); | |||
return arr; | |||
} | |||
function Tasker() { | function Tasker() { | ||
this[TASKS] = new Set(); | this[TASKS] = new Set(); | ||
this[WAITING] = new Set(); | this[WAITING] = new Set(); | ||
this[ERRORS] = []; | |||
} | } | ||
Tasker.prototype.push = function push() { | Tasker.prototype.push = function push() { | ||
var tasker = this; | var tasker = this; | ||
var items = arguments; | var items = arguments; | ||
if(items[0] && typeof items[0][Symbol.iterator] === 'function') items = Array.from(items[0]); | if(items[0] && typeof items[0][Symbol.iterator] === 'function') items = Array.from(items[0]); | ||
else items = Array.from(items); | else items = Array.from(items); | ||
items.forEach(function(item) { | items.forEach(function(item) { | ||
if(typeof item === 'function') tasker[TASKS].add(item); | if(typeof item === 'function') tasker[TASKS].add(item); | ||
else tasker[WAITING].add(item); | else tasker[WAITING].add(item); | ||
}); | }); | ||
return this; | return this; | ||
}; | }; | ||
Tasker.prototype.wait = function wait() { | Tasker.prototype.wait = function wait() { | ||
var tasker = this; | var tasker = this; | ||
return | |||
if(this[ERRORS].length) return Promise.reject(this[ERRORS].slice()); | |||
else return Promise.all(capture(tasker[WAITING])).then(function handle() { | |||
var captured = capture(tasker[WAITING]); | |||
if(captured.length) return Promise.all(captured).then(handle); | |||
}); | |||
}; | |||
Tasker.prototype.waitSettled = function waitSettled() { | |||
var tasker = this; | |||
return Promise.allSettled(capture(tasker[WAITING])).then(function handle() { | |||
var captured = capture(tasker[WAITING]); | |||
if(captured.length) return Promise.allSettled(captured).then(handle); | |||
}); | }); | ||
}; | }; | ||
42번째 줄: | 54번째 줄: | ||
var tasker = this; | var tasker = this; | ||
this[TASKS].forEach(function(task) { | this[TASKS].forEach(function(task) { | ||
tasker[WAITING].add(task()); | try { | ||
tasker[WAITING].add(task()); | |||
} catch(error) { | |||
tasker[ERRORS].push({ | |||
task: task, | |||
error: error | |||
}); | |||
} | |||
}); | }); | ||
return this; | return this; | ||
}; | }; | ||
Tasker.prototype.catch = function(handler) { | |||
if(this[ERRORS].length) handler(this[ERRORS].slice()); // Copy this[ERRORS] array | |||
return this; | |||
}; | |||
window.Tasker = Tasker; | window.Tasker = Tasker; | ||
function ModuleTasker() { | |||
Tasker.call(this); | |||
this.done = false; | |||
} | |||
function | ModuleTasker.prototype = Object.create(Tasker.prototype); | ||
ModuleTasker.prototype.constructor = ModuleTasker; | |||
ModuleTasker.prototype.run = function run() { | |||
var tasker = this; | var tasker = this; | ||
setTimeout(function() { | |||
capture(tasker[TASKS]).forEach(function(task) { | |||
if(typeof task === 'string') tasker[WAITING].add(mw.loader.using(task)); | |||
else try { | |||
tasker[WAITING].add(task()); | |||
} catch(error) { | |||
tasker[ERRORS].push({ | |||
task: task, | |||
error: error | |||
}); | |||
} | |||
}); | |||
tasker.done = true; | |||
}, 0); | |||
return this; | return this; | ||
}; | }; | ||
ModuleTasker.prototype.push = function() { | |||
Tasker.prototype.push.apply(this, arguments); | Tasker.prototype.push.apply(this, arguments); | ||
if( | if(this.done) this.run(); | ||
return this; | return this; | ||
}; | }; | ||
taskers | |||
var taskers = { | |||
renderer: new ModuleTasker(), | |||
handler: new ModuleTasker(), | |||
trigger: new ModuleTasker() | |||
}; | }; | ||
window.registerRenderer = function registerRenderer() { | window.registerRenderer = function registerRenderer() { | ||
102번째 줄: | 129번째 줄: | ||
$(function() { | $(function() { | ||
mw.loader.using(RLPAGEMODULES).always/*finally*/(function() { | |||
mw.loader.using(RLPAGEMODULES).always(function() { | return taskers.renderer.run().waitSettled().catch(console.error); | ||
}).then(function() { | |||
return taskers.renderer.run(). | return taskers.handler.run().waitSettled().catch(console.error); | ||
}). | }).then(function() { | ||
taskers.trigger.run().catch(console.error); | |||
return taskers.handler.run(). | |||
}). | |||
taskers.trigger.run(); | |||
}); | }); | ||
}); | }); |
2023년 3월 27일 (월) 21:55 기준 최신판
/**
* 0. 모든 패키지가 로딩되고 DOM이 준비될때까지 기다립니다. 오류 여부는 상관없습니다.
* 1. renderer: DOM 요소를 만들거나 수정합니다.
* 2. handler: 이벤트를 예약합니다.
* 3. trigger: 사용자 개입 없이 바로 시작되는 작업입니다.
**/
var TASKS = Symbol('tasks_queue');
var WAITING = Symbol('waiting_queue');
var ERRORS = Symbol('errors');
function capture(queue) {
var arr = Array.from(queue);
queue.clear();
return arr;
}
function Tasker() {
this[TASKS] = new Set();
this[WAITING] = new Set();
this[ERRORS] = [];
}
Tasker.prototype.push = function push() {
var tasker = this;
var items = arguments;
if(items[0] && typeof items[0][Symbol.iterator] === 'function') items = Array.from(items[0]);
else items = Array.from(items);
items.forEach(function(item) {
if(typeof item === 'function') tasker[TASKS].add(item);
else tasker[WAITING].add(item);
});
return this;
};
Tasker.prototype.wait = function wait() {
var tasker = this;
if(this[ERRORS].length) return Promise.reject(this[ERRORS].slice());
else return Promise.all(capture(tasker[WAITING])).then(function handle() {
var captured = capture(tasker[WAITING]);
if(captured.length) return Promise.all(captured).then(handle);
});
};
Tasker.prototype.waitSettled = function waitSettled() {
var tasker = this;
return Promise.allSettled(capture(tasker[WAITING])).then(function handle() {
var captured = capture(tasker[WAITING]);
if(captured.length) return Promise.allSettled(captured).then(handle);
});
};
Tasker.prototype.run = function run() {
var tasker = this;
this[TASKS].forEach(function(task) {
try {
tasker[WAITING].add(task());
} catch(error) {
tasker[ERRORS].push({
task: task,
error: error
});
}
});
return this;
};
Tasker.prototype.catch = function(handler) {
if(this[ERRORS].length) handler(this[ERRORS].slice()); // Copy this[ERRORS] array
return this;
};
window.Tasker = Tasker;
function ModuleTasker() {
Tasker.call(this);
this.done = false;
}
ModuleTasker.prototype = Object.create(Tasker.prototype);
ModuleTasker.prototype.constructor = ModuleTasker;
ModuleTasker.prototype.run = function run() {
var tasker = this;
setTimeout(function() {
capture(tasker[TASKS]).forEach(function(task) {
if(typeof task === 'string') tasker[WAITING].add(mw.loader.using(task));
else try {
tasker[WAITING].add(task());
} catch(error) {
tasker[ERRORS].push({
task: task,
error: error
});
}
});
tasker.done = true;
}, 0);
return this;
};
ModuleTasker.prototype.push = function() {
Tasker.prototype.push.apply(this, arguments);
if(this.done) this.run();
return this;
};
var taskers = {
renderer: new ModuleTasker(),
handler: new ModuleTasker(),
trigger: new ModuleTasker()
};
window.registerRenderer = function registerRenderer() {
var renderers = arguments;
if(renderers[0] && typeof renderers[0][Symbol.iterator] === 'function') renderers = renderers[0];
taskers.renderer.push(renderers);
};
window.registerHandler = function registerHandler() {
var handlers = arguments;
if(handlers[0] && typeof handlers[0][Symbol.iterator] === 'function') handlers = handlers[0];
taskers.handler.push(handlers);
};
window.registerTrigger = function registerTrigger() {
var triggers = arguments;
if(triggers[0] && typeof triggers[0][Symbol.iterator] === 'function') triggers = triggers[0];
taskers.trigger.push(triggers);
};
$(function() {
mw.loader.using(RLPAGEMODULES).always/*finally*/(function() {
return taskers.renderer.run().waitSettled().catch(console.error);
}).then(function() {
return taskers.handler.run().waitSettled().catch(console.error);
}).then(function() {
taskers.trigger.run().catch(console.error);
});
});