📚

依存関係のあるタスクの実行

2024/05/19に公開
import {Subject, combineLatest} from 'rxjs';
import {map} from 'rxjs/operators';

// シグナルを表すSubjectを作成
const signal1 = new Subject<boolean>();
const signal2 = new Subject<boolean>();
const signal3 = new Subject<boolean>();

// combineLatestを使用して、すべてのシグナルの最新の値を組み合わせる
const allSignals = combineLatest([signal1, signal2, signal3]).pipe(
    map(([s1, s2, s3]) => s1 && s2 && s3)
);

// すべてのシグナルが励起状態(true)になったら、処理を実行
allSignals.subscribe((excited) => {
    if (excited) {
        console.log('すべてのシグナルが励起状態になりました');
        // 励起状態になったときの処理をここに記述
    }
});

// シグナルを励起状態にする
signal1.next(true);
signal2.next(true);
signal3.next(true);


class Task {
    signalDone = new Subject<boolean>();

    tasks: Task[];

    constructor(tasks: Task[]) {
        this.tasks = tasks;
    }

    async perform() {
        // 依存するタスクがすべて完了したときの処理
    }

    async run() {
        const allTasks = this.tasks.map(task => task.signalDone);
        const allSignals = combineLatest(allTasks).pipe(
            map(signals => signals.every(signal => signal))
        );


        if (allTasks.length === 0) {
            await this.perform();
            this.signalDone.next(true);
        } else {
            allSignals.subscribe(async (excited) => {
                if (excited) {
                    await this.perform();
                    this.signalDone.next(true);
                }
            });
        }
    }
}


const sleep = async (milliseconds: number) => {
    return await new Promise((resolve) => setTimeout(resolve, milliseconds));
};

const just_task = async (name: string, time: number) => {
    console.log(`start task ${name}`);
    await sleep(time * 1000)
    console.log(`end task ${name}`);
};

const cycle_task = async (name: string, time: number, count: number) => {
    let task_counter = 0;
    console.log(`start task ${name}`);
    while(task_counter < count) {
        console.log(`task ${name} call`)
        task_counter ++;
        if (task_counter < count) {
            await sleep(time * 1000);
        }
    }
    console.log(`end task ${name}`);
};


class Task1 extends Task {
    async perform() {
        await  just_task("1 coffee water", 4);
    }
}

class Task2 extends Task {
    async perform() {
        await cycle_task("2", 3, 5)
    }
}

class Task3 extends Task {
    async perform() {
        await  just_task("3 cooking", 15);
    }
}

class Task4 extends Task {
    async perform() {
        await cycle_task("4 newspaper", 5, 4)
    }
}

class Task5 extends Task {
    async perform() {
        await  just_task("5 coffee drip", 5);
    }
}

class Task6 extends Task {
    async perform() {
        await  just_task("6 change", 6);
    }
}

class Task7 extends Task {
    async perform() {
        await  just_task("7 wash", 13);
    }
}

class Task8 extends Task {
    async perform() {
        await  just_task("8 breakfirst", 9);
    }
}

class Task9 extends Task {
    async perform() {
        await  just_task("9 laundry", 5);
    }
}

class Task10 extends Task {
    async perform() {
        await  just_task("10 drink coffee", 5);
    }
}

class Task11 extends Task {
    async perform() {
        await  just_task("11 wash dish", 4);
    }
}

class Task12 extends Task {
    async perform() {
        await  just_task("12 ready to go out", 3);
    }
}

class Task13 extends Task {
    async perform() {
        await  just_task("13 read news paper", 8);
    }
}

class Task14 extends Task {
    async perform() {
        console.log("14 go out")
    }
}

let tasksArray: Task[] = [];

let task1 = new Task1([]);
let task2 = new Task2([]);
let task3 = new Task3([]);
let task4 = new Task4([]);
let task5 = new Task5([task1]);
let task6 = new Task6([task2]);
let task7 = new Task7([task6]);
let task8 = new Task8([task3, task5, task6]);
let task9 = new Task9([task7]);
let task10 = new Task10([task5, task9]);
let task11 = new Task11([task8, task10]);
let task12 = new Task12([task8]);
let task13 = new Task13([task4]);
let task14 = new Task14([task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13]);

tasksArray.push(task1);
tasksArray.push(task2);
tasksArray.push(task3);
tasksArray.push(task4);
tasksArray.push(task5);
tasksArray.push(task6);
tasksArray.push(task7);
tasksArray.push(task8);
tasksArray.push(task9);
tasksArray.push(task10);
tasksArray.push(task11);
tasksArray.push(task12);
tasksArray.push(task13);
tasksArray.push(task14);


tasksArray.forEach(task => {
    task.run();
})


task14.signalDone.subscribe((excited: boolean) => {
    if (excited) {
        console.log('Task14 has been completed!');
    }
});

実行結果

すべてのシグナルが励起状態になりました
start task 1 coffee water
start task 2
task 2 call
start task 3 cooking
start task 4 newspaper
task 4 newspaper call
task 2 call
end task 1 coffee water
start task 5 coffee drip
task 4 newspaper call
task 2 call
end task 5 coffee drip
task 2 call
task 4 newspaper call
task 2 call
end task 2
start task 6 change
end task 3 cooking
task 4 newspaper call
end task 4 newspaper
start task 13 read news paper
end task 6 change
start task 7 wash
start task 8 breakfirst
end task 13 read news paper
end task 8 breakfirst
start task 12 ready to go out
end task 12 ready to go out
end task 7 wash
start task 9 laundry
end task 9 laundry
start task 10 drink coffee
end task 10 drink coffee
start task 11 wash dish
end task 11 wash dish
14 go out
Task14 has been completed!

Discussion