diff options
Diffstat (limited to 'common/once.js')
-rw-r--r-- | common/once.js | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/common/once.js b/common/once.js new file mode 100644 index 0000000..1842a47 --- /dev/null +++ b/common/once.js @@ -0,0 +1,44 @@ +/** +* 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)); + } + + function make_once(result_producer) + { + let state = {waiting : [], ready : false, result : undefined}; + assign_result(state, result_producer); + return () => get_result(state); + } + + window.make_once = make_once; +})(); |