Promise Mutex Example
Do you want transaction async? here!
by Ukjin Yang
HTML
<pre id="out"></pre>
JavaScript
// for get value async simulation
function dispatchTest(value) {
return new Promise(function(resolve){
setTimeout(() => resolve(value), Math.random()*100);
});
}
// for set value async simulation
function lazyPushTest(array, value) {
return new Promise(function(resolve){
setTimeout(() => { array.push(value); resolve(array); }, Math.random()*100);
});
}
// mutex!
function Mutex() {
let mutex = Promise.resolve();
this.lock = () => {
let begin = {unlock: () => {}};
mutex = mutex.then(() => {
return new Promise(begin);
});
return new Promise(resolve => {
begin = resolve;
});
};
}
(() => {
// datas
const data1 = ['data1'], data2 = ['data2'], data3 = ['data3'];
async function setWithoutMutex(value){
const data = await dispatchTest(data1);
data.push(value);
await lazyPushTest(data, value + ' copy');
return data;
}
setWithoutMutex('1');
setWithoutMutex('2');
const mutex = new Mutex();
async function setWithMutex(value){
const unlock = await mutex.lock();
const data = await dispatchTest(data2);
data.push(value);
await lazyPushTest(data, value + ' copy');
unlock();
return data;
}
setWithMutex('1');
setWithMutex('2');
// see in browser console log.
//console.log(data1);
//console.log(data2);
//console.log(data3);
// simulate output
setTimeout(() => {
const out = document.querySelector('#out'), log = s => out.appendChild(document.createTextNode(JSON.stringify(s) + '\n'));
log(data1);
log(data2);
log(data3);
}, 500);
})();