神戸プログラミングアカデミーのブログ

「未経験から」「スキルアップ」「起業を目指す」無料で学べる神戸のプログラミング学校&学習コミュニティ

async/await

youtu.be

同期処理/非同期処理とは?

同期処理

コードが呼ばれたときに、処理が終わるまで、プロセスを止めること。

C,C++,Python,Ruby

非同期処理

コードが呼ばれたときは、処理をする命令をするだけで、プロセスを止めない。

処理が終わったら「終わったよー」といって通知してくれるシステム。

UI系の言語はこっちが多い。JavaScript, Swift, Dart

サンプル

const fs = require('fs');
let id
let i = 0;
id = setInterval(()=>{
  console.log(i++)
},1)

setTimeout(()=>{
  if(false){
    const data = fs.readFileSync(大きいファイル)
    clearInterval(id)    
  }else{
    fs.readFile(大きいファイル, (err, data) => {
      clearInterval(id)    
    });
  }
}, 200)

これはJavaScriptのいいところ!

だけど、

1秒待って

Aと出力

1.2秒待って

Bと出力

1.6秒待って

Cと出力

1.1秒待って

Dと出力

1.2秒待って

Eと出力

1秒待って

Fと出力

1.6秒待って

Gと出力

これをプログラムで書くと

setTimeout(() => {
  console.log('A')
  setTimeout(() => {
    console.log('B')
    setTimeout(() => {
      console.log('C')
      setTimeout(() => {
        console.log('D')
        setTimeout(() => {
          console.log('E')
          setTimeout(() => {
            console.log('F')
            setTimeout(() => {
              console.log('G')
            }, 1600)
          }, 1000)
        }, 1200)
      }, 1100)
    }, 1600)
  }, 1200)
}, 1000)

Promise

developer.mozilla.org

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

sleep(1000).then(()=>{
  console.log('A')
  return sleep(1200)
}).then(()=>{
  console.log('B')
  return sleep(1600)
}).then(()=>{
  console.log('C')
  return sleep(1100)
}).then(()=>{
  console.log('D')
  return sleep(1200)
}).then(()=>{
  console.log('E')
  return sleep(1000)
}).then(()=>{
  console.log('F')
  return sleep(1600)
}).then(()=>{
  console.log('G')
})

ちょっと良くなった

async/await

async/awaitはPromiseをもっとスッキリ書けるようにしてくれている構文

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function main(){
  await sleep(1000)
  console.log('A')
  await sleep(1200)
  console.log('B')
  await sleep(1600)
  console.log('C')
  await sleep(1100)
  console.log('D')
  await sleep(1200)
  console.log('E')
  await sleep(1000)
  console.log('F')
  await sleep(1600)
  console.log('G')
}
main()

Promiseを返す関数はawaitで待つことができる。 ただしawaitはasyncの定義されている関数内でしか呼ぶことができない。

とにかく、async/awaitで書けないか?を常に調べる。Promiseを返すバージョンの関数がないかを調べる。できるだけasync/awaitを使う。