diff options
Diffstat (limited to 'common/once.mjs')
-rw-r--r-- | common/once.mjs | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/common/once.mjs b/common/once.mjs new file mode 100644 index 0000000..0f76366 --- /dev/null +++ b/common/once.mjs @@ -0,0 +1,42 @@ +/** +* Myext feature initialization promise +* +* Copyright (C) 2021 Wojtek Kosior +* +* Dual-licensed under: +* - 0BSD license +* - GPLv3 or (at your option) any later version +*/ + +"use strict"; + +/* + * This module provides an easy way to wrap an async function into a promise + * so that it only gets executed once. + */ + +async function assign_result(state, result_producer) +{ + state.result = await result_producer(); + state.ready = true; + for (let cb of state.waiting) + setTimeout(cb, 0, state.result); + state.waiting = undefined; +} + +async function get_result(state) +{ + if (state.ready) + return state.result; + + return new Promise((resolve, reject) => state.waiting.push(resolve)); +} + +export function make_once(result_producer) +{ + let state = {waiting : [], ready : false, result : undefined}; + assign_result(state, result_producer); + return () => get_result(state); +} + +export default make_once; |