Promise 실례

7235 단어 ES6
2 년 전부터 Promise 를 접 하 게 됐 는데, 그 때 는 좀 어리둥절 했 고, 교육 용 PPT 를 써 서 사내 회람 을 하 는 것 같 기도 했 는데, 지금 은 정말 부 끄 럽 고 난감 하 다. 최근 실천 을 통 해 Promise 에 대한 새로운 깨 달 음 을 기록 하고 있다.
처음에는 비동기 호출 부터
우 리 는 JS 가 단일 스 레 드 라 는 것 을 알 고 있 습 니 다.
우리 가 흔히 볼 수 있 는 몇 가지 비동기 처리 방법, setTimeout, ajax 요청, 그리고 jquery 안의 사건 처리 입 니 다.
군밤
우 리 는 비동기 작업 이 있 습 니 다. 2s 후에 user 데 이 터 를 생 성 한 다음 에 이 user 가 성인 인지 아 닌 지 판단 합 니 다. 전통 적 인 비동기 작업 과정 에서 우 리 는 다음 과 같은 코드 를 탁탁 적 었 습 니 다.
function generateUser() {
    var names = ['keviy','goof','Kouth','WANG','Li'];
    var age = Math.floor(Math.random() * 80);
    var user = {
      name:names[Math.floor(Math.random() * names.length)],
      age: age
    }
    return user;
}

function getAdults(isAdultCallback) {
  
  var user;
  
  setTimeout(()=> {
    user = generateUser();
    console.log('       ....');
    isAdultCallback && typeof isAdultCallback === 'function' && isAdultCallback(user);
  },2000)
  
}

function isAdultCallback(user) {
  if(user){
      if(user.age > 17){
        console.log('adult user...');
      } else {
        console.log('not adult...');
      }
  }

  console.log(user.name + ':' + user.age);
}


getAdults(isAdultCallback);

괜찮아 보 여요.만약 에 우리 가 성인 인지 아 닌 지 를 판단 한 후에 비동기 적 인 조작 을 해 야 한다 면 배경 에서 인터페이스 로 해당 PC 방 의 회원 인지 아 닌 지 를 판단 해 야 한다. 회원 이 라면 직접 켜 기 에 성공 하고 그렇지 않 으 면 가입 회원 페이지 로 뛰 어 내린다.
function generateUser() {
    var names = ['keviy','goof','Kouth','WANG','Li'];
    var age = Math.floor(Math.random() * 80);
    var user = {
      name:names[Math.floor(Math.random() * names.length)],
      age: age
    }
    return user;
}

function getAdults(isAdultCallback) {
  
  var user;
  
  setTimeout(()=> {
    user = generateUser();
    console.log('user       ....');
    isAdultCallback && typeof isAdultCallback === 'function' && isAdultCallback(user);
  },2000)
  
}

function isVip(user, isVipCallback) {
  setTimeout(() => {
    console.log('            Vip...');
    user.isVip = !user.isVip;
    isVipCallback(user);
  },3000)
}

function isAdultCallback(user) {
  if(user){
      if(user.age > 17){
        console.log('adult user...');
        console.log(user.name + ':' + user.age);
        //          vip
        isVip(user, isVipCallback);
      } else {
        console.log('not adult...');
      }
  }
}

function isVipCallback(user) {
  if(user && user.isVip) {
    console.log('    !welcome ' + user.name);
  } else {
    console.log('you are not the vip yet. please go to register first!')
  }
}


getAdults(isAdultCallback);

위의 코드 는 2 층 밖 에 없 지만 이미 복잡 해 보인다.이런 겹겹이 끼 워 넣 는 방식 은 조금도 우아 하지 않다.
삼 Promise 대 법
Promise 는 ES6 의 새로운 특성 으로 비동기 작업 을 우아 하 게 수행 할 수 있 습 니 다.그것 은 전통 적 인 실현 과 마찬가지 로 '미래 어느 순간 에 어떤 사건 을 호출 하 겠 다 고 약속 하 겠 다' 는 뜻 이다.
첫 번 째 실현 에 대해 우 리 는 Promise 로 다음 과 같이 실현 합 니 다.
function generateUser() {
    var names = ['keviy','goof','Kouth','WANG','Li'];
    var age = Math.floor(Math.random() * 80);
    var user = {
      name:names[Math.floor(Math.random() * names.length)],
      age: age
    }
    return user;
}

function getAdults() {
  var p = new Promise((resolve, reject) => {
    var user = generateUser();
    setTimeout(() => {
       console.log('user       ...');
       if(user && user.age > 17) {
         resolve(user);
       } else {
         reject(user)
       }
       
    }, 2000)
  })
  
  return p;
}

getAdults().then(user => {
   console.log('adult user...');
   console.log(user.name + ':' + user.age);
}, user => {
   console.log('not adult...');
    console.log(user.name + ':' + user.age);
})

전통 적 인 실현 에 비해 우 리 는 Promise 대상 을 설명 하고 데 이 터 를 되 돌려 달라 고 요청 한 후에 성공 하면 resolve 를 호출 합 니 다. 그렇지 않 으 면 reject 를 호출 합 니 다. 그리고 then 방법 에서 두 개의 인 자 를 받 습 니 다. 하 나 는 resolve 의 반전 이 고 다른 하 나 는 reject 의 반전 입 니 다.이 두 리 턴 함수 에 서 는 주로 남 은 업무 논 리 를 실현 한다.
Promise 의 장점 은 데이터 획득 과 업무 논 리 를 분리 해 처리 하고 개발 과정 에서 한 가지 일 에 만 집중 하 는 것 이다.
위의 장점 이 여전히 억 지 스 럽 다 고 생각한다 면, 우 리 는 isVip 의 논 리 를 추가 하여 Promise 가 어떻게 실현 되 는 지 살 펴 보 자.
function getAdults() {
  var p = new Promise((resolve, reject) => {
    var user = generateUser();
    setTimeout(() => {
       console.log('user       ...');
       if(user && user.age > 17) {
         resolve(user);
       } else {
         reject(user)
       }
       
    }, 2000)
  })
  
  return p;
}

function isVip(user) {
  var p = new Promise((resolve, reject) => {
    setTimeout(() => {
      user.isVip = user.name.indexOf('o') > -1;
      if(user.isVip){
        resolve(user);
      } else {
        reject(user);
      }
    }, 1000)
                      
  })
  
  return p;
}

getAdults()
 .then(isVip)
 .then(user => {
    console.log('adult user...');
    console.log(user.name + ':' + user.age);
    console.log('    !welcome ' + user.name);
 })
 .catch((user) => {
    if(user.age < 18) {
      console.log('not adult...');
    } else {
      console.log('you are not the vip yet. please go to register first!');
    }
    console.log(user.name + ':' + user.age);
  }
)

위의 실현 에 있어 서 매번 요청 을 하나의 promise 로 작성 하고 외부 콜 백 에 의존 하지 않 으 며 뒤의 호출 에서 체인 호출 을 한 후에 데 이 터 를 업무 논리 적 으로 처리 합 니 다. 이러한 쓰기 방법 은 코드 의 재 활용 성 을 강화 할 수 있 습 니 다.
위의 쓰 기 는 직렬 적 인 쓰기 이 고 Promise 는 병렬 적 인 요청 에 도 문법 이 있 습 니 다.만약 에 두 개의 자원 을 동시에 요청 하고 선후 순서 가 없다 면 우 리 는 다음 과 같이 쓸 수 있다.
function getWidth() {
  return new Promise((resolve, reject) => {
      setTimeout(
        resolve(5)
      ,1000)
 
  })
}

function getHeight() {
  return new Promise((resolve, reject) => {
      setTimeout(
        resolve(4)
      ,1000)
  })
}

Promise.all([getWidth(), getHeight()]).then((result) => {
  console.log('result:');
  console.log(result); // [5, 4]
})

병렬 라면 되 돌아 오 는 결 과 는 배열 입 니 다.
Promise. race () 는 여러 요청 중 가장 빨리 데 이 터 를 얻 은 것 을 되 돌려 주 는 것 을 말 합 니 다. 다시 한 번 예 를 들 어 보 겠 습 니 다.
function getWidth() {
  return new Promise((resolve, reject) => {
      setTimeout(resolve, 10000, 1)
 
  })
}

function getHeight() {
  return new Promise((resolve, reject) => {
      setTimeout(resolve , 20000, 2)
  })
}

function getLength() {
  return new Promise((resolve, reject) => {
      setTimeout(resolve, 1000, 3)
  })
}

Promise.race([getHeight(), getWidth(), getLength()]).then((result) => {
  console.log('result:');
  console.log(result); // "result:" 3
})

사총 결
이상 은 Promise 의 용법 입 니 다. Promise 는 본질 적 으로 비동기 데이터 획득 과 업무 논 리 를 분리 하여 개발 자 들 로 하여 금 업무 와 데 이 터 를 동시에 고려 하지 않 고 한 가지 사물 에 전념 하 게 합 니 다.또한 체인 호출 을 할 때 겹겹이 포 함 된 지옥 문 제 를 피하 고 코드 의 재 활용 성 을 강화 합 니 다.
PS: 오늘 의 마지막 코드 가 setTimeout 을 다음 과 같은 형식 으로 쓰 면 코드 결과 가 틀 립 니 다. 어떤 귀 요 미 가 왜 그런 지 아 세 요?
setTimeout(resolve(2) , 20000)

좋은 웹페이지 즐겨찾기