kintone JavaScriptカスタマイズでよく聞くコールバック関数とはなにか

kintoneのJavaScriptカスタマイズをきっかけに、時折初学者にレクチャーすることがあるのですが、やはりいくつか難しいポイントがあります。
その中でも特に、イメージがわかりにくくてこまっていると相談を受けるのが「コールバック関数」です。
コールバック関数とはなにか？というのをJavaScriptカスタマイズで実例を上げつつ説明してみたいと思います。
※ここでの説明は表現上の正確さよりも分かりやすさを重視していますのでご留意ください。

## コールバック関数とは？
コールバック関数自体は「何かが終わった後に実行される関数」という理解でいいかと思います。
下記は、料理を作る`makeDinner`関数と料理が作り終わったあとに実行してほしい関数`callMe`を例として用意してみました。

```javascript
function makeDinner(callback) {
    console.log('料理を作っています...');
    setTimeout(() => {
        console.log('料理ができました！');
        callback();
    }, 2000); // 2秒後に実行
}
```

```javascript
function callMe() {
    console.log('おいしい！いただきます！');
}

makeDinner(callMe);
```

`makeDinner`はコールバック関数を受け付けることができ、今回`callMe`を渡していますが、実際にはどのような関数でも渡せます。
繰り返しになりますが、このように「何かが終わった後に実行される関数」がコールバック関数ということになります。
この例では`callMe`がコールバック関数であり、`makeDinner`はコールバック関数を受け付けることができる関数ということになります。
![CleanShot 2024-12-08 at 23.35.17@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31957/ba7e4777-4fe2-1485-6a44-e965ebfbbbb0.png)


## kintoneでの使い方: イベント処理

kintoneでは、イベントが発生したときにコールバック関数を使います。

```javascript
kintone.events.on('イベント名', function(event) {
    // イベント発生時の処理
    return event;
});
```

何気なくつかっていると思いますが、`kintone.events.on`という関数は「指定されたイベントが実行されたら渡された関数を実行する」関数ということになります。
ここでは引数のなかに直接関数をかいていますが、もちろん定義した関数を渡す、でも問題ありません。

```javascript

function hogeFunc(event) {
    // イベント発生時の処理
    return event;    
}

kintone.events.on('イベント名', hogeFunk);
```


## 実践1: レコードのタイトルを表示

もう少し具体の例として、以下のコードでは、レコード詳細画面が表示された際にタイトルを表示します。

```javascript
kintone.events.on('app.record.detail.show', function(event) {
    const record = event.record;
    console.log('このレコードのタイトルは:', record.タイトル.value);
    return event;
});
```

ポイント
- イベント: 'app.record.detail.show'（レコード詳細画面が表示されたとき）。
- 処理内容: レコード情報のタイトルをコンソールに出力。

## 実践2: REST APIの使用例

API呼び出しも交えた例です。
レコード詳細画面でAPIを呼び出し、レコード情報を取得します。

```javascript
kintone.events.on('app.record.detail.show', function(event) {
    const recordId = kintone.app.record.getId();const RecordId = kintone.app.record.getId();
    kintone.api('/k/v1/record', 'GET', { app: kintone.app.getId(), id: recordId }, 
        function(resp) { // コールバック関数
            console.log('レコード情報:', resp.record);
            alert('データ取得が完了しました！');
        });
    return event;
});
```

つまり`kintone.events.on`も`kintone.api`も両方ともコールバック関数を受け付ける関数ということになります。

ただし、コールバック関数の弱点として入れ子構造が深くなってコードの読みやすさが落ちてしまうことがあると思います。この例においてもAPI呼び出したら成功したら実行するコールバック関数はまぁまぁわかりにくいと思います。

そのためasync/awaitを利用した書き方も`kintone.api`はサポートしており今はそれを利用するのがおすすめです。
[Promiseのかわりにasync/awaitを使ってみよう
](https://cybozu.dev/ja/kintone/tips/development/customize/development-know-how/javascript-customize-middle-async-await/)

## 実践3: ボタンをクリックしてアラートを表示

下記は一覧画面にボタンを置き、そのボタンが押されたらアラートを表示するコードですが、これも「ボタンが押されたら実行する」というコールバック関数が実行される例です。
`button.onclick`に関数を指定することでボタンが押されたときにその関数が実行されます。

```javascript
(function() {
    'use strict';

    kintone.events.on('app.record.index.show', function(event) {
        // ボタンを作成
        const button = document.createElement('button');
        button.textContent = 'クリックしてください';

        // TODO: ボタンがクリックされたときの処理を追加
        button.onclick = function() {
            alert('ボタンがクリックされました！');
        };

        kintone.app.getHeaderMenuSpaceElement().appendChild(button);
        return event;
    });
})();
```

## 最後に
ここまで買いておもいましたが、関数を渡せる、というそれ自体が難しい感覚かもしれませんね。
それは学んで慣れていけば「そういうものか」というふうになると思いますのであまり心配しなくてもいいかなと思います。
イメージつきづらいことやわかりにくいことがあれば質問があれば答えますのでJSカスタマイズを学習されている方はなにか有りましたらぜひ