Node.jsデザインパターンを読んでいる中で
並行処理を学んだので書いていく。
並行処理の基本パターン
const tasks = [task1, task2, task3]
let completed = 0
tasks.forEach(task => {
task(() => {
if(++completed === tasks.length) {
finish();
}
})
})
function finish() {
console.log('all tasks finished!!')
}
function task1(callback) {
setTimeout(()=> {
console.log('task1 finished')
callback()
}, 1000)
}
function task2(callback) {
setTimeout(()=> {
console.log('task2 finished')
callback()
}, 2000)
}
function task3(callback) {
setTimeout(()=> {
console.log('task3 finished')
callback()
}, 3000)
}
これを実行すると、コンソールは以下のようになる。
> "task1 finished"
> "task2 finished"
> "task3 finished"
> "all tasks finished!!"
"all tasks finished!!"をコールバック関数にせず、同期的に処理すると以下のようになる。
const tasks = [task1, task2, task3]
let completed = 0
tasks.forEach(task => {
task()
if(++completed === tasks.length) {
finish();
}
})
function finish() {
console.log('all tasks finished!!')
}
function task1() {
setTimeout(()=> {
console.log('task1 finished')
// callback()
}, 1000)
}
function task2() {
setTimeout(()=> {
console.log('task2 finished')
// callback()
}, 2000)
}
function task3() {
setTimeout(()=> {
console.log('task3 finished')
// callback()
}, 3000)
}
コンソールには以下のように吐き出された。
> "all tasks finished!!"
> "task1 finished"
> "task2 finished"
> "task3 finished"
次に、本当に並列処理がなされているのかを Data.now()
を使って確認してみる。
const tasks = [task1, task2, task3]
let completed = 0
tasks.forEach(task => {
const startTime = Date.now()
task(startTime, () => {
if(++completed === tasks.length) {
finish();
}
})
})
function finish() {
console.log('all tasks finished!!')
}
function task1(startTime, callback) {
console.log(`task1 startTime: ${startTime}`)
setTimeout(()=> {
console.log(`task1 finished ${Date.now()}`)
callback()
}, 1000)
}
function task2(startTime, callback) {
console.log(`task2 startTime: ${startTime}`)
setTimeout(()=> {
console.log(`task2 finished ${Date.now()}`)
callback()
}, 2000)
}
function task3(startTime, callback) {
console.log(`task3 startTime: ${startTime}`)
setTimeout(()=> {
console.log(`task3 finished ${Date.now()}`)
callback()
}, 3000)
}
これを実行すると、以下のようになる。
> "task1 startTime: 1639648461429"
> "task2 startTime: 1639648461429"
> "task3 startTime: 1639648461429"
> "task1 finished 1639648462431"
> "task2 finished 1639648463430"
> "task3 finished 1639648464434"
> "all tasks finished!!"
タイムスタンプなので見づらいが、ちゃんと同じ時間に3つのタスクがstartしていて、それぞれ約1秒後、約2秒後、約3秒後に終了していることがわかる。