Edited at

【JS】setTimeoutを用いた、非同期処理入門


概要

setTimeoutを用いて、非同期処理の処理順をまとめました。

コールバック -> Promise -> async/await の順に説明する。


setTimeout

基本構文

setTimeout('コールバック関数', 'タイムアウト時間')

1秒後にhogeを出力する。


function callback(){
console.log('hoge')
}

setTimeout(callback, 1000)


出力結果

hoge


alt

無名関数を用いて書く。

setTimeout(function(){ console.log('hoge') }, 1000)

アロー演算子を用いて書く。


setTimeout(() => { console.log('hoge') }, 1000)

アロー演算子を用いて書く。(中括弧を省略)

setTimeout(() => console.log('hoge'), 1000)


処理順

非同期処理の処理順を確認する。

console.log(1)

setTimeout(() => console.log(2), 1000)
console.log(3)


出力結果

1

3
2

alt

timeout時間 0秒 でも、処理順は変わらない。

console.log(1)

setTimeout(() => console.log(2), 0)
console.log(3)


出力結果

1

3
2

alt


コールバック地獄

非同期処理が複数重なると、コールバック地獄に陥る。

setTimeout(() => {

console.log(1)
setTimeout(() => {
console.log(2)
setTimeout(() => {
console.log(3)
}, 1000)
}, 1000)
}, 1000)


出力結果

1

2
3

alt


コールバック地獄の回避方法

Promise化すると、thenを用いたメソッドチェーンで処理を繋げられる。

new Promise(function(resolve) {

resolve('Hello')
}).then(function(value) {
console.log(value) // Hello
return 'World'
}).then(function(value) {
console.log(value) // World
})


出力結果

Hello

World

resolve、returnの値が、コールバック関数の引数になる。

アロー演算子を用いて書き換えてみる。

new Promise(resolve => resolve('Hello'))

.then(value => {
console.log(value) // Hello
return 'World'
}).then(value => {
console.log(value) // World
})


出力結果

Hello

World

コールバック地獄を、Promiseで書き直してみる。

function sleep(ms) {

return new Promise(function(resolve) {
setTimeout(function() {
resolve()
}, ms)
})
}

sleep(1000)
.then(function() {
console.log(1)
return sleep(1000)
}).then(function() {
console.log(2)
return sleep(1000)
}).then(function() {
console.log(3)
})


出力結果

1

2
3

Promiseとアロー演算子を用いて書き換えてみる。

const sleep = ms => new Promise(resolve => setTimeout(() => resolve(), ms))

sleep(1000)
.then(() => {
console.log(1)
return sleep(1000)
}).then(() => {
console.log(2)
return sleep(1000)
}).then(() => {
console.log(3)
})


出力結果

1

2
3

alt

async関数内で、Promise関数にawaitを用いると、同期的に処理できる。

function sleep(ms) {

return new Promise(function(resolve) {
setTimeout(resolve, ms)
})
}

async function asyncFunc() {
await sleep(1000)
console.log(1)
await sleep(1000)
console.log(2)
await sleep(1000)
console.log(3)
}

asyncFunc()


出力結果

1

2
3

async/await とアロー演算子を用いた場合

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const asyncFunc = async () => {
await sleep(1000)
console.log(1)
await sleep(1000)
console.log(2)
await sleep(1000)
console.log(3)
}

asyncFunc()


出力結果

1

2
3

更に、即時関数を用いて書くと、簡潔に書ける。

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

!(async () => {
await sleep(1000)
console.log(1)
await sleep(1000)
console.log(2)
await sleep(1000)
console.log(3)
})()


出力結果

1

2
3

alt


まとめ

非同期処理の処理順をまとめました。

async/await を用いることで、とても簡潔に書けます。

間違い・指摘等があればコメントお願いします。


参考文献