Можно так:
class Foo {
constructor() {
this.queue = [];
}
tick(cb) {
this.queue.push(cb);
return this;
}
then(cb) {
return this.queue.reduce((acc, fn) =>
acc.then(fn), Promise.resolve()).then(cb);
}
}
Вариант в прототипном стиле:
function Foo() {
this.queue = [];
}
Foo.prototype.tick = function(cb) {
this.queue.push(cb);
return this;
}
Foo.prototype.then = function(cb) {
return this.queue.reduce(function(acc, fn) {
return acc.then(fn);
}, Promise.resolve()).then(cb);
}
Пример использования:
const foo = new Foo();
const task1 = () =>
new Promise(resolve => {
setTimeout(() => {
console.log('task1');
resolve('Done!');
}, 1000);
});
const task2 = arg =>
new Promise(resolve => {
setTimeout(() => {
console.log('task2');
resolve(arg);
}, 1000);
});
foo.tick(task1)
.tick(task2)
.then(console.log);
/* result:
task1
task2
Done!
*/