fukke.cafe

Callback時代の関数をPromise化する

Callback時代の関数たち

node.jsの標準モジュールにはcallback時代の関数が多数存在します。
例えば fs.writeFile()
https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback
この関数は第3引数にcallback関数を取ります。
fs.writeFile("path", data, (err) => {
  if (err) throw err;
});
ぱっと見は、全然使いやすそうに見えるのですが
例えば
fs.copyFile(, , err => {
    fs.chmod(, , err => {
        fs.readdir(, , (err, file) => {
            ...
        })
    })
})
このように結果を使ってさらに処理したい場合、
どんどんネストが深くなっていきとても見にくくなります。
これを Callback Hellと言うそうです。
この問題を解決するために、Promiseを使用します。
Promiseはcallbackに変わる非同期処理です。

Promise化する

Promiseを返す関数を作成します。
Promiseには正しく解決したことを表すresolveと問題が起きたことを表すrejectがあります。
よって、callback関数でerrが存在した場合はreject それ以外の場合にresolveを返すように実装します。
import * as fs from "fs";
const writeFileAsync = (file: string, data: string): Promise<void> => {
  return new Promise((resolve, reject) => {
    fs.writeFile(file, data, (err) => err ? reject(err) : resolve());
  });
};
Promiseを返す関数が実装できればこの関数を await するように使うことで非同期の実行を待つことが出来ます。
またtry-catchでrejectの補足も行いましょう。
const main = async () => {
  try {
    await writeFileAsync(file, data);
  } catch (error) { // rejectの補足
    console.error(error);
  }
};

参考文献

https://techblog.yahoo.co.jp/javascript/nodejs/callback-to-promise/

公開日 2020/06/19

目次

Thanks you for reading.