コールバックからPromiseへ変換
JavaScriptにおけるコールバックAPIからPromiseへの変換
コールバック関数は、非同期処理の完了時に呼び出される関数です。これに対して、Promiseは、非同期操作の結果を表現するオブジェクトで、成功または失敗の状態を保持します。
コールバックAPIからPromiseへの変換方法
Promiseコンストラクタを使用する
function fetchData(url, callback) { // ... (非同期処理) callback(error, data); } function fetchDataPromise(url) { return new Promise((resolve, reject) => { fetchData(url, (error, data) => { if (error) { reject(error); } else { resolve(data); } }); }); }
async/awaitを使用する
async function fetchDataAsync(url) { return new Promise((resolve, reject) => { fetchData(url, (error, data) => { if (error) { reject(error); } else { resolve(data); } }); }); }
例: Node.jsのfsモジュール
const fs = require('fs');
// コールバック関数を使用
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// Promiseを使用
fs.readFile('file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
// async/awaitを使用
async function readData() {
try {
const data = await fs.promises.readFile('file.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
}
readData();
注意
- Node.jsのfsモジュールは、Promiseベースのメソッドを提供しているため、直接使用することができます。
- async/awaitは、Promiseをより同期的なコードのように扱うための構文糖衣です。
- Promiseは、非同期処理の成功または失敗のどちらかの結果を返すため、エラー処理が重要です。
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
Promiseを使用
fs.readFile('file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
async function readData() {
try {
const data = await fs.promises.readFile('file.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
}
readData();
HTTPリクエスト
const https = require('https');
https.get('https://api.example.com/data', (res) => {
res.on('data', (chunk) => {
console.log(chunk);
});
});
const https = require('https');
const util = require('util');
const get = util.promisify(https.get);
get('https://api.example.com/data')
.then(res => {
return new Promise((resolve, reject) => {
res.on('data', (chunk) => {
resolve(chunk);
});
res.on('error', reject);
});
})
.then(data => console.log(data))
.catch(err => console.error(err));
const https = require('https');
const util = require('util');
const get = util.promisify(https.get);
async function fetchData() {
try {
const res = await get('https://api.example.com/data');
const data = await new Promise((resolve, reject) => {
res.on('data', (chunk) => {
resolve(chunk);
});
res.on('error', reject);
});
console.log(data);
} catch (err) {
console.error(err);
}
}
fetchData();
Promiseライブラリを使用する
Node.jsの標準ライブラリには、Promiseを扱うためのユーティリティ関数である util.promisify
が提供されています。これを使用して、コールバックベースの関数をPromiseベースの関数に変換することができます。
const util = require('util');
// コールバックベースの関数
function asyncOperation(callback) {
// ... (非同期処理)
callback(null, 'result');
}
// Promiseベースの関数に変換
const promisifiedOperation = util.promisify(asyncOperation);
promisifiedOperation()
.then(result => console.log(result))
.catch(err => console.error(err));
第三者ライブラリを使用する
Node.jsのエコシステムには、Promiseを扱うためのさまざまなサードパーティライブラリが存在します。これらのライブラリは、コールバックベースの関数をPromiseベースの関数に変換する機能を提供している場合があります。
例えば、bluebird
や q
などのライブラリを使用することができます。
手動でPromiseをラップする
もし、上記の方法が適用できない場合は、手動でコールバックベースの関数をPromiseでラップすることができます。
function asyncOperation(callback) {
// ... (非同期処理)
callback(null, 'result');
}
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (err, result) => {
if (err) {
reject(err);
} else {
resolve(re sult);
}
});
});
};
}
const promisifiedOperation = promisify(asyncOperation);
promisifiedOperation()
.then(result => console.log(result))
.catch(err => console.error(err));
javascript node.js callback