promisification

lee jae hwan·2022년 8월 5일

javascript

목록 보기
86/107

일반적인 콜백함수

function loadScript(scriptSrc, callback){
  let scriptElement = document.createElement('script');
  scriptElement.src = scriptSrc;
  scriptElement.onload = ()=>callback(null,'ok');
  scriptElement.onerror = ()=>callback(new Error('load fail'));
  document.head.append(scriptElement);
}

function callback(error, val){
  if(error){
    console.log('Error : '+ error.message);
  }else{
    console.log(val);
  }
}

loadScript('test12.js',callback);

스크립트파일과 콜백함수를 같이 전달한다.


loadScript함수를 promise화하는 방법
1. loadScript함수를 인자로받아 데코레이팅하는 함수를 만들고 promise화된 함수를 반환한다.
2. 반환된 함수는 src만 인자로받고 promise객체를 반환한다.
3. 반환된 함수에 핸들러를 추가하여 callback을 호출한다.

function loadScript(scriptSrc, callback){
  let scriptElement = document.createElement('script');
  scriptElement.src = scriptSrc;
  scriptElement.onload = ()=>callback(null,'ok');
  scriptElement.onerror = ()=>callback(new Error('load fail'));
  document.head.append(scriptElement);
}

function callback(er, val){
  if(er){
    console.log(er);
  }else{
    console.log(val);
  }
}

function promiseLoadScript(fn){
  return function(src){
    return new Promise((resolve)=>{
      fn(src,(err,val)=>{
        if(err){
          throw new Error("error1");
        }else{
          resolve(val);
        }
      });
    })
  }
}

loadScript = promiseLoadScript(loadScript);
loadScript('test1.js')
.then((val)=>{
  callback(null,val);
})
.catch(er=>{
  callback(er,null);
})

loadScript, callback함수를 수정하지 않고 그대로 사용하고 loadScript를 promise화하여 사용한다.




promiseLoadScript를 일반화하여 promise데코레이팅하는 함수를 만들어 보자.

function loadScript(scriptSrc, callback){
  let scriptElement = document.createElement('script');
  scriptElement.src = scriptSrc;
  scriptElement.onload = ()=>callback(null,'ok');
  scriptElement.onerror = ()=>callback(new Error('load fail'));
  document.head.append(scriptElement);
}

function decoratorPromisify(fn){
  return function(src){
    return new Promise((resolve,reject)=>{
      fn(src,(err,val)=>{
        if(err){
          reject(err);
        }else{
          resolve(val);
        }
      });
    });
  }
}

let loadScriptPromise = decoratorPromisify(loadScript);
loadScriptPromise('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js')
.then(console.log)
.catch(console.log)




callback(null,'ok'); 인자갯수가 여러개일 경우를 적용해보자

function loadScript(scriptSrc, callback){
  let scriptElement = document.createElement('script');
  scriptElement.src = scriptSrc;
  scriptElement.onload = ()=>callback(null,'ok');
  scriptElement.onerror = ()=>callback(new Error('load fail'));
  document.head.append(scriptElement);
}

function decoratorPromisify(fn){
  return function(src){
    return new Promise((resolve,reject)=>{
      fn(src,(err,...args)=>{
        if(err){
          reject(err);
        }else{
          resolve(args.length>1?args:args[0]);
        }
      });
    });
  }
}

let loadScriptPromise = decoratorPromisify(loadScript);
loadScriptPromise('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js')
.then(console.log)
.catch(console.log)

0개의 댓글