Promise asynchronous callback solves the problem of callback hell

1. What is promise

  1. Mainly used for asynchronous computing
  2. Asynchronous operations can be queued, executed in the desired order, and return results that meet the expectations
  3. You can pass and manipulate promises between objects, helping us deal with queues

2. The problem of asynchronous callback:

  1. The previous processing of asynchrony was handled in the form of a pure callback function
  2. It is easy to enter the callback hell, depriving the function of the ability to return
  3. The problem can be solved, but it is difficult to read and maintain
  4. A little carelessness will lead to callback hell -deep nesting level, difficult to maintain

3. Introduction to promise

  1. A promise is an object. The difference between an object and a function is that an object can save state, but a function cannot (except closures)
  2. Does not deprive the function of the ability to return, so there is no need to pass the callback layer by layer, callback to obtain data
  3. Code style, easy to understand and easy to maintain
  4. Consolidation of multiple asynchronous waits is easy to solve

4. Detailed Promise

The role of resolve is to change the state of the Promise object from "unfinished" to " successful " (that is, from pending to resolved), call when the asynchronous operation succeeds, and pass the result of the asynchronous operation as a parameter; the
role of reject is , Change the state of the Promise object from "unfinished" to " failed " (that is, from pending to rejected), call when the asynchronous operation fails, and pass the error reported by the asynchronous operation as a parameter.
A promise has three states:

  1. pending [to be determined] initial state
  2. fulfilled [fulfilled] operation succeeded
  3. rejected [Rejected] Operation failed

When the promise state changes , the response function in **then()** will be triggered to process the subsequent steps; once the
promise state changes, it will not change .
There are only two possibilities for the state of the Promise object to change:

  1. Change from pending to fulfilled
  2. Change from pending to rejected.

As long as these two situations occur, the state will be frozen and will not change anymore.

5、.then()

  1. Receive two functions as parameters, representing fulfilled (success) and rejected (failure)
  2. .then() returns a new Promise instance, so it can be chained
  3. When the current Promise state changes, .then() selects a specific state response function to execute according to its final state
  4. The status response function can return a new promise, or other values, or if it does not return a value, we can consider it to return a null;
  5. If a new promise is returned, the next level .then() will be executed after the state of the new promise changes
  6. If any other value is returned, the next level will be executed immediately.then()

6. Two methods of error handling:

Promise will automatically catch the internal exception and hand it to the rejected response function for processing.

(1) The first error handling

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

(2) The second type of error handling

<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( () => {错误处理逻辑})

It is recommended to use the second method, which is more clear and easy to read, and can capture all the previous errors (can capture N then callback errors)

7, the usage of promise

(1) Common usage:

Asynchronous operation and timer are put together. If the timer is triggered first, it will be considered as a timeout and the user will be notified;

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

(2) Usage in reality

The callback is packaged as a Promise, which has two obvious benefits:

  1. Good readability
  2. The returned result can be added to any Promise queue

8. Comparison of callback hell and promise

(1) Callback hell

/***
   第一步:找到北京的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 writing

// 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)
      }
    })
  })
}

Guess you like

Origin blog.csdn.net/Serena_tz/article/details/113972067