なんで非同期が必要なのか?

基本的に関数は実行した順番に実行される。(当たり前)

console.log(1)
console.log(2)

// 1
// 2

でも、重たい処理があると順番がおかしくなることも…

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

// 1
// 3
// 〜10秒後〜
// 2

考えようによっては便利で、処理が終わるまで待ってるとなかなかページが表示されず、イライラするので、先に簡単に準備ができるもの(文字とか)を表示しといて、後から時間がかかるもの(画像とか)を表示するとストレスが減る

これが非同期処理

一方、一度データを拾ってきて、その内容について色々したい時にはコレだと詰むので、処理が完了してから、次の処理を行いたい…

そこで、同期処理を行う

コールバックで行う場合は

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

// 1
// 〜10秒後〜
// 2
// 〜10秒後〜
// 3

この程度であれば問題はないが、コールバックの回数が多くなると地獄。

そこでPromiseを使う。

console.log(1)
const a = new Promise((x,y) => { //xはうまく行った時、yはうまくいかなかった時の値を格納できる
	
	console.log(2)
 	setTimeout(() => {
  	console.log(3)
    x("成功")  
  },10000)
  // y("失敗")  //これを発動するとsetTimeout()より先に処理され失敗判定になるので、catchが発動する
  
})

a.then((ok) => { // このokにはxに突っ込んだ値か入る
	console.log(5);
	console.log(ok);
	return "チェーンできます"
}).then((ok2) => { // returnの値がok2に入る。同じ変数名でも問題なし
	console.log(5);
	console.log(ok2);
})

a.catch((miss) => {
	console.log(6);
	console.log(miss);
})

これをさらに簡単にしたのがasync/await

時間がかかる処理が終わるかどうかをPromiseでチェックして、その値が返ってくるのをawiteで待つ感じ。

async function x() {  //async を関数につけるとawaitを使える
    console.log(1)
    const a = await y()
    console.log(4)
    return a
}


function y() { //時間がかかる処理
    return new Promise((x, y) => { //xはうまく行った時、yはうまくいかなかった時の値を格納できる
        console.log(2)
        setTimeout(() => {
            console.log(3)
            x("成功")
        }, 10000)
    })
}

x().then((b) => {
    console.log(5)
    console.log(b)
})

x()をthenで書くと以下。

function x() {  //async を使わなかった場合
    console.log(1)
    const a = y()
    console.log(4) // ここは3より先に発動
    return a
}


function y() { //時間がかかる処理
    return new Promise((x, y) => { //xはうまく行った時、yはうまくいかなかった時の値を格納できる
        console.log(2)
        setTimeout(() => {
            console.log(3)
            x("成功")
        }, 10000)
    })
}

x().then((b) => {
    console.log(5)
    console.log(b)
})

コメント