Promise.allを複数入れ子で使ってみる

どれも同じに見えて、test7.jsのケースだけが結果が変わってくるのと、
test4.jsのケースはたまにあるという話。


### ケース１ [Promise.all([Promise.all(promises), promise4])]
```javascript:test1.js:
const main = async () => {
  const promises = [];
  for (let i = 1; i < 4; i++) {
    promises.push(new Promise((resolve) => {
      setTimeout(() => {
        const msg = `promise${i}:${performance.now()}`;
        console.log(msg);
        resolve(msg) ;
      }, 1000 ) ;
    }));    
  }
  const promise4 = new Promise((resolve) => {
    setTimeout(() => {
      const msg = `promise4:${performance.now()}`;
      console.log(msg);
      resolve(msg) ;
    }, 1000 ) ;
  });
  
  console.log(`start:${performance.now()}`);
  const [result1, result2] =  await Promise.all([Promise.all(promises), promise4]);
  console.log('result1', result1);
  console.log('result2', result2);
  console.log(`end:${performance.now()}`);
};
main();

```

結果
```bash
$ node test1.js
start:91.1770830154419
promise1:1092.4741251468658
promise2:1094.0931251049042
promise3:1094.3359999656677
promise4:1094.573417186737
result1 [
  'promise1:1092.4741251468658',
  'promise2:1094.0931251049042',
  'promise3:1094.3359999656677'
]
result2 promise4:1094.573417186737
end:1098.4679169654846
```

### ケース2 [Promise.all([promises, promise4])]

```javascript:test2.js
const main = async () => {
  const promises = [];
  for (let i = 1; i < 4; i++) {
    promises.push(new Promise((resolve) => {
      setTimeout(() => {
        const msg = `promise${i}:${performance.now()}`;
        console.log(msg);
        resolve(msg) ;
      }, 1000 ) ;
    }));    
  }
  const promise4 = new Promise((resolve) => {
    setTimeout(() => {
      const msg = `promise4:${performance.now()}`;
      console.log(msg);
      resolve(msg) ;
    }, 1000 ) ;
  });
  
  console.log(`start:${performance.now()}`);
  const [result1, result2] =  await Promise.all([promises, promise4]);
  console.log('result1', await Promise.all(result1));
  console.log('result2', result2);
  console.log(`end:${performance.now()}`);
};
main();
```


```bash
$ node test2.js
start:95.8585410118103
promise1:1098.136207818985
promise2:1098.6249158382416
promise3:1098.8037497997284
promise4:1099.002624988556
result1 [
  'promise1:1098.136207818985',
  'promise2:1098.6249158382416',
  'promise3:1098.8037497997284'
]
result2 promise4:1099.002624988556
end:1104.8773748874664
````

### ケース3 [Promise.all(promises)]

```js:test3.js

const main = async () => {
  const promises = [];
  for (let i = 1; i < 4; i++) {
    promises.push(new Promise((resolve) => {
      setTimeout(() => {
        const msg = `promise${i}:${performance.now()}`;
        console.log(msg);
        resolve(msg) ;
      }, 1000 ) ;
    }));    
  }
  const promise4 = new Promise((resolve) => {
    setTimeout(() => {
      const msg = `promise4:${performance.now()}`;
      console.log(msg);
      resolve(msg) ;
    }, 1000 ) ;
  });
  
  console.log(`start:${performance.now()}`);
  const result1 =  await Promise.all(promises);
  const result2 =  await promise4;
  console.log('result1', result1);
  console.log('result2', result2);
  console.log(`end:${performance.now()}`);
};
main();
```

```bash
$　node test3.js
start:20.573333024978638
promise1:1022.4034171104431
promise2:1022.521791934967
promise3:1022.5552499294281
promise4:1022.5932080745697
result1 [
  'promise1:1022.4034171104431',
  'promise2:1022.521791934967',
  'promise3:1022.5552499294281'
]
result2 promise4:1022.5932080745697
end:1023.645457983017
```

### ケース4 functionから呼ばれるケース [Promise.all([Promise.all(promises), func1(4)])]

```js:test4.js
const func1 = (n) => { return new Promise((resolve) => {
  setTimeout(() => {
    const msg = `promise${n}:${performance.now()}`;
    console.log(msg);
    resolve(msg) ;
  }, 1000 ) ;
})};

const main = async () => {
  const promises = [];

  for (let i = 1; i < 4; i++) {
    promises.push(func1(i));
  }

  console.log(`start:${performance.now()}`);
  const [result1, result2] =  await Promise.all([Promise.all(promises), func1(4)]);
  console.log('result1', result1);
  console.log('result2', result2);
  console.log(`end:${performance.now()}`);
};
main();
```

```
$ node
start:96.04895901679993
promise1:1096.53125
promise2:1096.9413750171661
promise3:1096.981791973114
promise4:1099.3429999351501
result1 [
  'promise1:1096.53125',
  'promise2:1096.9413750171661',
  'promise3:1096.981791973114'
]
result2 promise4:1099.3429999351501
end:1101.1944589614868
```

### ケース5 functionから呼ばれる [Promise.all([promises, func1(4)])]

```js:test5.js
const func1 = (n) => { return new Promise((resolve) => {
  setTimeout(() => {
    const msg = `promise${n}:${performance.now()}`;
    console.log(msg);
    resolve(msg) ;
  }, 1000 ) ;
})};

const main = async () => {
  const promises = [];

  for (let i = 1; i < 4; i++) {
    promises.push(func1(i)); // 1~3の処理が非同期で実行される
  }

  console.log(`start:${performance.now()}`);
  const [result1, result2] =  await Promise.all([promises, func1(4)]); 
  console.log('result1', await Promise.all(result1));
  console.log('result2', result2);
  console.log(`end:${performance.now()}`);

};
main();
```

```bash
$ node test5.js
start:95.46229195594788
promise1:1096.5545828342438
promise2:1096.8492918014526
promise3:1096.950166940689
promise4:1100.5722079277039
result1 [
  'promise1:1096.5545828342438',
  'promise2:1096.8492918014526',
  'promise3:1096.950166940689'
]
result2 promise4:1100.5722079277039
end:1105.3650000095367
```

### ケース6 functionから呼ばれる & func1(4)が先に呼ばれる [Promise.all(promises)]

```js:test6.js
const func1 = (n) => { return new Promise((resolve) => {
  setTimeout(() => {
    const msg = `promise${n}:${performance.now()}`;
    console.log(msg);
    resolve(msg) ;
  }, 1000 ) ;
})};

const main = async () => {
  const promises = [];

  for (let i = 1; i < 4; i++) {
    promises.push(func1(i)); // 1~3の処理が非同期で実行される
  }
  const func2 = func1(4);　　// ４の処理が非同期で実行される
  console.log(`start:${performance.now()}`);
  const result1 = await Promise.all(promises); // 1~3の処理が完了するのを待つ
  const result2 = await func2; // 4の処理が完了するのを待つ
  console.log('result1', result1);
  console.log('result2', result2);
  console.log(`end:${performance.now()}`);

};
main();
```

```bash
$ node test6.js
start:100.14412498474121
promise1:1100.7576248645782
promise2:1101.0685830116272
promise3:1101.1569168567657
promise6:1101.2393329143524
result1 [
  'promise1:1100.7576248645782',
  'promise2:1101.0685830116272',
  'promise3:1101.1569168567657'
]
result2 promise6:1101.23
```


### ケース7 functionから呼ばれる＆func1(4)が後で呼ばれる [Promise.all(promises)]

```js:test7.js

const func1 = (n) => { return new Promise((resolve) => {
  setTimeout(() => {
    const msg = `promise${n}:${performance.now()}`;
    console.log(msg);
    resolve(msg) ;
  }, 1000 ) ;
})};

const main = async () => {
  const promises = [];

  for (let i = 1; i < 4; i++) {
    promises.push(func1(i));
  }
  console.log(`start:${performance.now()}`);
  const result1 = await Promise.all(promises);
  const result2 = await func1(4); // Promise.allの後に呼ばれる
  console.log('result1', result1);
  console.log('result2', result2);
  console.log(`end:${performance.now()}`);

};
main();
```

```bash
$ node test7.js
start:126.15004205703735
promise1:1127.4714589118958
promise2:1128.0532920360565
promise3:1128.1695420742035
promise4:2129.4043340682983
result1 [
  'promise1:1127.4714589118958',
  'promise2:1128.0532920360565',
  'promise3:1128.1695420742035'
]
result2 promise4:2129.4043340682983
end:2135.1092500686646 
```

このケースは1~3が終わった後に待ってから4が実行されるので2秒かかってしまう。