Promise 비동기 콜백은 콜백 지옥의 문제를 해결합니다.

1. 약속이란

  1. 주로 비동기 계산에 사용
  2. 비동기 작업을 대기열에 추가하고 원하는 순서로 실행하고 기대치를 충족하는 결과를 반환 할 수 있습니다.
  3. 객체간에 약속을 전달하고 조작 할 수 있으므로 대기열을 처리하는 데 도움이됩니다.

2. 비동기 콜백의 문제 :

  1. 이전의 비동기 처리 순수한 콜백 함수의 형태 로 처리 되었습니다.
  2. 콜백 지옥에 들어가기 쉬우 며, 반환 기능을 빼앗 깁니다.
  3. 문제는 해결 될 수 있지만 읽고 유지 하기가 어렵습니다.
  4. 약간의 부주의로 이어질 것입니다 지옥 콜백 - 깊은 중첩 수준을, 어려운 유지

3. 약속 소개

  1. promise는 객체입니다. 객체와 함수의 차이점은 객체는 상태를 저장할 수 있지만 함수는 저장할 수 없다는 것입니다 (클로저 제외).
  2. 반환 기능의 기능을 박탈하지 않으므로 데이터를 얻기 위해 콜백 레이어를 레이어별로 전달할 필요가 없습니다.
  3. 이해하기 쉽고 유지하기 쉬운 코드 스타일
  4. 여러 비동기 대기의 통합을 쉽게 해결할 수 있습니다.

4. 세부 약속

확인의 역할은 Promise 개체의 상태를 "미완료"에서 " 성공 "으로 (즉, 보류에서 해결됨으로) 변경하고, 비동기 작업이 성공할 때 호출하고, 비동기 작업의 결과를 매개 변수로 전달하는 것입니다.
거부역할은 다음 과 같습니다. Promise 객체의 상태를 "미완료"에서 " 실패 "(즉, 보류에서 거부로)로 변경하고, 비동기 작업이 실패 할 때 호출하고, 비동기 작업에서보고 한 오류를 매개 변수로 전달합니다. .
약속에는 세 가지 상태가 있습니다.

  1. 보류중인 [결정 예정] 초기 상태
  2. 처리됨 [이행 됨] 작업 성공
  3. 거부 됨 [거부 됨] 작업 실패

경우 약속 상태 변화 에 응답 함수 ** 후 () ** 후속 단계를 처리하도록 트리거되는 상기 한번
, 그 변화하지 약속 상태 변화 .
Promise 개체의 상태가 변경 될 수있는 가능성은 두 가지뿐입니다.

  1. 보류에서 이행으로 변경
  2. 보류에서 거부로 변경합니다.

이 두 가지 상황이 발생하는 한 상태는 동결 되고 더 이상 변경되지 않습니다.

5 、 .then ()

  1. 이행 (성공) 및 거부 (실패)를 나타내는 두 개의 함수를 매개 변수로 수신합니다.
  2. .then ()은 새로운 Promise 인스턴스를 반환하므로 연결할 수 있습니다.
  3. 현재 Promise 상태가 변경되면 .then ()은 최종 상태에 따라 실행할 특정 상태 응답 함수를 선택합니다.
  4. 상태 응답 함수는 새로운 promise 또는 다른 값을 반환 할 수 있습니다. 또는 값을 반환하지 않는 경우 null을 반환하는 것으로 간주 할 수 있습니다.
  5. 새로운 promise가 반환되면 새로운 promise의 상태가 변경된 후 다음 수준 .then ()이 실행됩니다.
  6. 다른 값이 반환되면 다음 레벨이 즉시 실행됩니다.

6. 오류 처리의 두 가지 방법 :

Promise는 자동으로 내부 예외를 포착하여 처리를 위해 거부 된 응답 기능에 전달합니다.

(1) 첫 번째 오류 처리

<script>
        new Promise((resolve,reject)=>{
    
    
            setTimeout(()=>{
    
    
                reject('bye')
            },2000)
        }).then((val)=>{
    
    
            console.log(val)
        },(err)=>{
    
    
            console.log("Error",error)
        })
    </script>

(2) 두 번째 유형의 오류 처리

<script>
        new Promise((resolve)=>{
    
    
            setTimeout(()=>{
    
    
                throw new Error('bye')
            },2000)
        }).then((val)=>{
    
    
            console.log(val)
        }).catch(error=>{
    
    
            console.log("Error",error)
        })
</script>
第一种:reject('错误信息').then(() => {}, () => {错误处理逻辑})
第二种:throw new Error('错误信息').catch( () => {错误处理逻辑})

더 명확하고 읽기 쉽고 이전 오류를 모두 캡처 할 수있는 두 번째 방법을 사용하는 것이 좋습니다 (N 다음 콜백 오류를 캡처 할 수 있음).

7, 약속의 사용법

(1) 일반적인 사용법 :

비동기 작업과 타이머가 합쳐져 ​​타이머가 먼저 트리거되면 타임 아웃으로 간주되어 사용자에게 알림이 전송됩니다.

例如:我们要从远程的服务家在资源如果5000ms还没有加载过来我们就告知用户加载失败

(2) 실제 사용

콜백은 Promise로 패키징되어 두 가지 분명한 이점이 있습니다.

  1. 좋은 가독성
  2. 반환 된 결과는 모든 Promise 대기열에 추가 할 수 있습니다.

8. 콜백 지옥과 약속의 비교

(1) 콜백 지옥

/***
   第一步:找到北京的id
   第二步:根据北京的id -> 找到北京公司的id
   第三步:根据北京公司的id -> 找到北京公司的详情
   目的:模拟链式调用、回调地狱
 ***/
 
 // 回调地狱
 // 请求第一个API: 地址在北京的公司的id
 $.ajax({
    
    
   url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/city',
   success (resCity) {
    
    
     let findCityId = resCity.filter(item => {
    
    
       if (item.id == 'c1') {
    
    
         return item
       }
     })[0].id
     
     $.ajax({
    
    
       //  请求第二个API: 根据上一个返回的在北京公司的id “findCityId”,找到北京公司的第一家公司的id
       url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/position-list',
       success (resPosition) {
    
    
         let findPostionId = resPosition.filter(item => {
    
    
           if(item.cityId == findCityId) {
    
    
             return item
           }
         })[0].id
         // 请求第三个API: 根据上一个API的id(findPostionId)找到具体公司,然后返回公司详情
         $.ajax({
    
    
           url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/company',
           success (resCom) {
    
    
             let comInfo = resCom.filter(item => {
    
    
               if (findPostionId == item.id) {
    
    
                 return item
               }
             })[0]
             console.log(comInfo)
           }
         })
       }
     })
   }
 })

(2) 약속 쓰기

// Promise 写法
  // 第一步:获取城市列表
  const cityList = new Promise((resolve, reject) => {
    
    
    $.ajax({
    
    
      url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/city',
      success (res) {
    
    
        resolve(res)
      }
    })
  })

  // 第二步:找到城市是北京的id
    cityList.then(res => {
    
    
      let findCityId = res.filter(item => {
    
    
        if (item.id == 'c1') {
    
    
          return item
        }
      })[0].id
      
      findCompanyId().then(res => {
    
    
        // 第三步(2):根据北京的id -> 找到北京公司的id
        let findPostionId = res.filter(item => {
    
    
            if(item.cityId == findCityId) {
    
    
              return item
            }
        })[0].id

        // 第四步(2):传入公司的id
        companyInfo(findPostionId)

      })

    })

  // 第三步(1):根据北京的id -> 找到北京公司的id
  function findCompanyId () {
    
    
    let aaa = new Promise((resolve, reject) => {
    
    
      $.ajax({
    
    
        url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/position-list',
        success (res) {
    
    
          resolve(res)
        }
      })
    })
    return aaa
  }

// 第四步:根据上一个API的id(findPostionId)找到具体公司,然后返回公司详情
function companyInfo (id) {
    
    
  let companyList = new Promise((resolve, reject) => {
    
    
    $.ajax({
    
    
      url: 'https://www.easy-mock.com/mock/5a52256ad408383e0e3868d7/lagou/company',
      success (res) {
    
    
        let comInfo = res.filter(item => {
    
    
            if (id == item.id) {
    
    
               return item
            }
        })[0]
        console.log(comInfo)
      }
    })
  })
}

추천

출처blog.csdn.net/Serena_tz/article/details/113972067