JS Mutex for Async

Async like sync!

by Ukjin Yang

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(() => {
    console.log(data1);
    console.log(data2);
    console.log(data3);
  }, 500);
  
})();