概要
setTimeoutを用いて、非同期処理の処理順をまとめました。
コールバック -> Promise -> async/await の順に説明する。
setTimeout
基本構文
setTimeout('コールバック関数', 'タイムアウト時間')
1秒後にhoge
を出力する。
function callback(){
console.log('hoge')
}
setTimeout(callback, 1000)
出力結果
hoge
無名関数を用いて書く。
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
timeout時間 0秒
でも、処理順は変わらない。
console.log(1)
setTimeout(() => console.log(2), 0)
console.log(3)
出力結果
1
3
2
コールバック地獄
非同期処理が複数重なると、コールバック地獄に陥る。
setTimeout(() => {
console.log(1)
setTimeout(() => {
console.log(2)
setTimeout(() => {
console.log(3)
}, 1000)
}, 1000)
}, 1000)
出力結果
1
2
3
コールバック地獄の回避方法
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
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
まとめ
非同期処理の処理順をまとめました。
async/await を用いることで、とても簡潔に書けます。
間違い・指摘等があればコメントお願いします。