【javascript】Macrotasks, Microtasks

# Macrotasks, Microtasks
* Macrotasks
    * タスクキューと呼ばれるもの。
        * setTimeoutなど
* Microtasks
    * ジョブキューと呼ばれる。タスクキューとは別の非同期処理の待ち行列
        * Promiseなどの非同期処理


## case

どの順番でコンソールに表示されるか？

```js

setTimeout(function task1() {
  console.log('task1');
});

new Promise(function promise(resolve) {
  console.log('promise');
  resolve();
}).then(function job1() {
  console.log('job1');
});

console.log('global end');

```

**以下の順番で実行される。**

1. グローバルタスク(同期処理)
    1. console.log('promise');
    1. console.log('global end');
1. マイクロタスク（非同期処理）
    1. console.log('job1');
1. マクロタスク（非同期処理）
    2. console.log('task1');


すなわち、コールスタックで呼ばれた種類によって登録先を決めている。
イベントループがマイクロタスク（ジョブキュー）なのかマクロタスク（タスクキュー）なのかを振り分けて実行する優先順位を決めている。

## 実行挙動の違い
* MicroTasks(ジョブキュー)
    * 登録されているすべてのジョブを実行する。
* MacroTasks(タスクキュー)
    * 登録されているタスクを一つづつ実行する。


| コールスタック | マイクロタスク | マクロタスク |
|:-----------|------------:|:------------:|
| context       | job1        | task1        |
|      | job2      | task2       |


* マイクロタスクを全て実行


| コールスタック | マイクロタスク | マクロタスク |
|:-----------|------------:|:------------:|
| context       |         | task1        |
|      |       | task2       |



* その後マクロタスクを一つ実行

| コールスタック | マイクロタスク | マクロタスク |
|:-----------|------------:|:------------:|
| context       |         |         |
|      |       | task2       |


* マイクロタスクが追加された場合

| コールスタック | マイクロタスク | マクロタスク |
|:-----------|------------:|:------------:|
| context       |   job1      |         |
|      |       | task2       |


* マイクロタスクが実行され

| コールスタック | マイクロタスク | マクロタスク |
|:-----------|------------:|:------------:|
| context       |         |         |
|      |       | task2       |

*　またマクロタスクが一つタスクを実行される。

| コールスタック | マイクロタスク | マクロタスク |
|:-----------|------------:|:------------:|
| context       |         |         |
|      |       |        |

## case2

* マクロタスクからマイクロタスクを読んだ場合はマクロタスクから実行される。
    * setTimeoutからPromiseをcall

```js

new Promise(function promise(resolve) {
  console.log('promise');

  setTimeout(function task1() {
    console.log('task1');
    resolve();
  });

}).then(function job1() {
  console.log('job1');
})

```

## case3

queueMicrotaskを利用するとマイクロタスクに差し込みができる。

```js

new Promise(function promise(resolve) {
  console.log('promise');

  setTimeout(function task1() {
    console.log('task1');
    resolve();
  });

}).then(function job1() {
  console.log('job1');
  queueMicrotask(function job4(){ //thenのなかでマイクロタスクを追加した。job2の前にjob４が実行される。
    console.log('job4')
  })
})
.then(function job2() {
  console.log('job2');
}).then(function job3() {
  console.log('job3');
})
console.log('global end');
```

## case3

* queueMicrotaskを使用するとマイクロタスクに差し込みができる。


```js

new Promise(function promise(resolve) {
  console.log('promise');

  setTimeout(function task1() {
    console.log('task1');
    resolve();
  });

}).then(function job1() {
  console.log('job1');
  queueMicrotask(function job4(){ //thenのなかでjob４を差し込んでいる。よってjob2の実行前にjob４が実行される。
    console.log('job4')
  })
})
.then(function job2() {
  console.log('job2');
}).then(function job3() {
  console.log('job3');
})
console.log('global end');

```

## タスクの代表例

* Macrotasks
    * setTimeout
    * setInterval
    * requestAnimationFrame
* Microtasks
    * Promise
    * queueMicrotask
    * MutationObserver