【Node.js】コールバック関数の同期呼び出しと非同期呼び出しについて
タグ:
JavaScript
Node.js
2章 非同期プログラミング より
マルチスレッドとイベントループ
function parseJSONAsync(json,callback){ setTimeout(()=>{ try{ callback(null,JSON.parse(json)) } catch (err) { callback(err) } }, 1000) } const cache = {} function parseJSONAsyncWithCache(json,callback){ const cached = cache[json] // キャッシュがあればキャッシュを返す if (cached){ callback(cached.err,cached.result) return } parseJSONAsync(json,(err,result) => { cache[json] = { err, result } callback(err,result) }) } parseJSONAsyncWithCache( '{"message": "Hello","to":"world"}', (err,result)=>{ console.log('1回目の結果',err,result) //コールバックの中で2回目を実行 parseJSONAsyncWithCache( '{"message": "Hello","to":"world"}', (err,result)=>{ console.log('2回目の結果',err,result) } ) console.log('2回目の呼び出し完了') } ) console.log('1回目の呼び出し完了')
1回目の呼び出し完了 1回目の結果 null { message: 'Hello', to: 'world' } 2回目の結果 null { message: 'Hello', to: 'world' } 2回目の呼び出し完了
parseJsonAsyncWithCacheが状況によってコールバックを同期的に実行したり非同期的に実行したりするため、一貫性が保てていない。 コールバックをパラメータとする関数は、それを常に同期的に実行するか、常に非同期的に実行するかのどちらかでなければならない。
// 略 const cache = {} function parseJSONAsyncWithCache(json,callback){ const cached = cache[json] // キャッシュがあればキャッシュを返す if (cached){ setTimeout(() => callback(cached.err,cached.result),0) return } parseJSONAsync(json,(err,result) => { cache[json] = { err, result } callback(err,result) }) } // 略
1回目の呼び出し完了 1回目の結果 null { message: 'Hello', to: 'world' } 2回目の呼び出し完了 2回目の結果 null { message: 'Hello', to: 'world' }