LoginSignup
57
39

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-02-02

概要

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 を用いることで、とても簡潔に書けます。
間違い・指摘等があればコメントお願いします。

参考文献

57
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
57
39