js 非同期関数の書き方


適当な関数
``` sync.js
function fx() {
    
    const a = 100 * 300;
    console.log('時間です');
  
    const ret = 'abc';
    
    let aa = [];
    for (let i = 0; i < 100; i++) {
      aa.push(i);
    }
  
    console.log(ret);
  
    const ret2 = 1000;
    
    const a2 = 'abc';
    let x = a2 + 'xyz';
    console.log(ret, ret2);

    
}

fx();
fx();
```
  結果は
  ```
  時間です
abc
abc 1000
時間です
abc
abc 1000
```
同期的に動いている。

```async.js
async function fx() {
    await Promise.resolve();  //ここで非同期

    const a = 100 * 300;
    console.log('時間です');
  
    await Promise.resolve(); //ここで非同期

    const ret = 'abc';
    let aa = [];
    for (let i = 0; i < 100; i++) {
      aa.push(i);
    }
  
    console.log(ret);
  
    await Promise.resolve(); //ここで非同期

    const ret2 = 1000;
    const a2 = 'abc';
    let x = a2 + 'xyz';
    console.log(ret, ret2);

    
}

fx();
fx();
```
`function`の前に`async`をいれ、ブレークするところに`await Promise.resolve();`をいれる。
  

  結果は

  ```
時間です
時間です
abc
abc
abc 1000
abc 1000
```
非同期になった。
ブレークしたところで、処理が切り替わる。


ちなみに
``` async.js
function delay() {
    return new Promise(resolve => setTimeout(resolve, 0));
  }


async function fx() {
    await delay();  //ここで非同期

    const a = 100 * 300;
    console.log('時間です');
  
    await delay(); //ここで非同期

    const ret = 'abc';
    let aa = [];
    for (let i = 0; i < 100; i++) {
      aa.push(i);
    }
  
    console.log(ret);
  
    await delay(); //ここで非同期

    const ret2 = 1000;
    const a2 = 'abc';
    let x = a2 + 'xyz';
    console.log(ret, ret2);

    
}

fx();
fx();

```
このように`setTimeout`をPromiseにくるんで渡してもよい。

``` delay.js
function delay() {
  return new Promise(resolve => setImmediate(resolve));
}
```

`setImmdiate`でもOK

### Promise.resolveとsetImmediateの違い

`Promise.resolve()`は**Microtask Queue**にタスクを追加する
`setImmediate()`は**Task Queue**にタスクを追加する

このため、`Promise.resolve()`の方が**優先的**に実行される

### 非同期関数から返り値を戻す場合
```async.js
async function fx() {
    await Promise.resolve();  //ここで非同期

    return '終わったよ'

}
    
    
fx().then(ret => {
    console.log(ret);
});
```
`retuen`で返して、`then`で受け取る。
`fx()`は`Promise`を返すから。

```async.js
async function fx() {
    await Promise.resolve();  //ここで非同期

    return '終わったよ'

}
    

(async () => {
    const ret = await fx(); 
    console.log(ret);
})();
```
`async`で書き換えてもOK。


 ### 長いループを非同期にする場合



  ```loop.js
  async function processAll() {
    const totalIterations = 510;
    const batchSize = 100;

    
    for (let i = 0; i < totalIterations; i += batchSize) {
        const start = i;
        const end = Math.min(i + batchSize, totalIterations); // 最後のバッチが100回未満の場合に対応

        await (async() => {
            console.log(`処理中: ${start}`);

            for (let i = start; i < end; i++) {
            
                // ここで実際の処理を行う（例: API 呼び出し、データ処理など）
            
            }
            await Promise.resolve();

        })();

        
    }
  
    console.log('すべての処理が完了しました');
}
  
processAll();
processAll();
```
100回ループするごとにブレークして非同期にループする。

```
処理中: 0
処理中: 0
処理中: 100
処理中: 100
処理中: 200
処理中: 200
処理中: 300
処理中: 300
処理中: 400
処理中: 400
処理中: 500
処理中: 500
すべての処理が完了しました
すべての処理が完了しました
```

内部のループを関数にしてもいい
``` loop.js
async function processBatch(start, end) {
    console.log(`処理中: ${start}`);

    for (let i = start; i < end; i++) {
      
      // ここで実際の処理を行う（例: API 呼び出し、データ処理など）
      
    }
    await Promise.resolve();
}
  

async function processAll() {
    const totalIterations = 510;
    const batchSize = 100;

    
    for (let i = 0; i < totalIterations; i += batchSize) {
        const start = i;
        const end = Math.min(i + batchSize, totalIterations); // 最後のバッチが100回未満の場合に対応

        await processBatch(start, end);


    }
  
    console.log('すべての処理が完了しました');
}
  
processAll();
processAll();
```

以上