JSFiddle - React, Tailwind, and code Playground
by lid0
HTML
<div id="app">
Ref Counter: {{ refCounter }}
<div style="background:#cfcfcf;padding:10px;">
<!-- <div>
Waiting for async to return true : <b v-if="await(doSomethingAsyn, null)">WASSAAAA, true </b><b v-else>__________</b>
</div> -->
<div>
<div class="app">
Await same signature, different default values ( will use first for both )
<!-- notice: the default will be ignored, due to memoization -->
<!-- we use the default null, to "detect" pending state. (promise will resolev to boolean) -->
<p>
<b>async status/response: {{ await( ()=>doSomethingAsyn(1,2,3), "123") }}</b>
</p>
<p>
<b>async status/response: {{ await( ()=>doSomethingAsyn(1,2,3), "123 you are not going to see this") }}</b>
</p>
<p>
<!-- bypass memoization by changing content of arrow function commend to change signature -->
<b>async status/response: {{ await( ()=>doSomethingAsyn(1,2,3/*uniqu_id*/), "123 bypassed cache") }}</b>
</p>
</div>
<div class="app">
Await Bypass cache with different arguments
<p>
<b>async status/response: {{ await( ()=>doSomethingAsyn(1,2,4), "124, new ") }}</b>
</p>
</div>
<div class="app">
awaitLazy (both will use the first default value):
<p>
<b>async status/response: {{ awaitLazy( doSomethingAsyn, "lazy call") }}</b>
</p>
<p>
<b>async status/response: {{ awaitLazy( doSomethingAsyn, "lazy call blabla") }}</b>
</p>
</div>
</div>
</div>
<pre style="font-size:11px">
Vue - await for async in vue expression such as in v-if
with arguments, we wrap in ()=>
await( ()=>doSomethingAsyn(1,2,3), "123")
Lazy ( no arguments )
awaitLazy( doSomethingAsyn, "lazy call")
</pre>
</div>
CSS
ul {
float: left;
}
.app {
margin-top: 3px;
border: 1px solid gray;
border-radius: 10px;
background: #cfc;
padding: 10px;
}
JavaScript
//author: lidlanca 2021 march 22
import { createApp, ref } from "https://unpkg.com/[email protected]/dist/vue.esm-browser.js";
const app = createApp({
setup() {
const awaitPromiseWeakMap = new WeakMap();
const awaitPromiseMap = new Map()
const refCounter = ref(0)
function awaitPromiseLazy(func, defaultValue) {
return awaitPromise(func, defaultValue, true);
}
/**
when passing a func with argument wrap in fat arrow ()=> someFunc(a,b,c)
This will allow us to create a string based signature of the function call, using function decomplilation
()=> someFunc(a,b,c)
is different than
()=> someFunc(a,b,FF)
func - an async function, or a function that when called returns an Thenable/Promise
defaultValue - the initial value used until the promise is resolved.
lazy - when true, the func will be used as key in the WeakMap.
*/
function awaitPromise(func, defaultValue, lazy) {
//
var funcSig;
var map;
if (lazy) {
var funcSig = func
map = awaitPromiseWeakMap
} else {
var funcSig = func.toString().replace(" ", "")
map = awaitPromiseMap
}
console.log("TICK", funcSig)
if (!awaitPromiseMap.has(funcSig)) {
var r = ref(defaultValue);
refCounter.value++;
awaitPromiseMap.set(funcSig, r);
func().then(function(v) { // update ref to resolved value
r.value = v
});
} else {
var r = awaitPromiseMap.get(funcSig)
}
return r.value
}
/**
doSomethingAsync - will do something and resolve after 3 seconds.
*/
async function doSomethingAsyn() {
return new Promise(
function(r) {
setTimeout(function() {
console.log("resolved")
r(true)
}, 3000)
})
}
return {
doSomethingAsyn,
await: awaitPromise,
awaitLazy:...