Promise非同期コールバックはコールバック地獄の問題を解決します

1.約束とは

  1. 主に非同期計算に使用されます
  2. 非同期操作はキューに入れられ、希望の順序で実行され、期待に応える結果を返すことができます
  3. オブジェクト間でpromiseを渡したり操作したりできるため、キューの処理に役立ちます

2.非同期コールバックの問題:

  1. 以前の非同期処理は純粋なコールバック関数の形式で処理されていました。
  2. コールバック地獄に入るのは簡単で、戻る能力の機能を奪います
  3. 問題は解決できますが、読み、維持するのは困難です
  4. 少しの不注意は、コールバック地獄につながります-深い入れ子レベル、維持するのが難しい

3.約束の紹介

  1. promiseはオブジェクトです。オブジェクトと関数の違いは、オブジェクトは状態を保存できますが、関数は保存できないことです(クロージャを除く)
  2. 戻る機能の機能を奪うことはないので、データを取得するためにコールバックをレイヤーごとに渡す必要はありません。
  3. コードスタイル、理解しやすく、保守しやすい
  4. 複数の非同期待機の統合は簡単に解決できます

4.詳細な約束

resolveの役割は、Promiseオブジェクトの状態を「unfinished」から「success」(つまり、保留中からresolved)に変更し、非同期操作が成功したときに呼び出し、非同期操作の結果をパラメーターとして渡すことです。
拒否役割は、Promiseオブジェクトの状態を「未完了」から「失敗」(つまり、保留中から拒否)に変更し、非同期操作が失敗したときに呼び出し、非同期操作によって報告されたエラーをパラメーターとして渡します。 。
約束には3つの状態があります。

  1. 保留中[未定]初期状態
  2. 実行された[実行された]操作が成功しました
  3. 拒否[拒否]操作に失敗しました

場合約束状態変化、**における応答関数次いで()**以降のステップを処理するようにトリガされ、一度
約束状態の変更は、変更されません
Promiseオブジェクトの状態が変化する可能性は2つだけです。

  1. 保留中から実行済みに変更
  2. 保留中から拒否に変更します。

これらの2つの状況が発生する限り、状態は凍結され、それ以上変化しません。

5、.then()

  1. 実行済み(成功)と拒否済み(失敗)を表す2つの関数をパラメーターとして受け取ります
  2. .then()は新しいPromiseインスタンスを返すので、チェーンすることができます
  3. 現在のPromise状態が変化すると、.then()は特定の状態応答関数を選択して、その最終状態に従って実行します。
  4. ステータス応答関数は、新しいpromiseまたは他の値を返すことができます。または、値を返さない場合は、nullを返すと見なすことができます。
  5. 新しいpromiseが返された場合、新しいpromiseの状態が変更された後、次のレベルの.then()が実行されます。
  6. 他の値が返された場合、次のレベルがすぐに実行されます。then()

6.エラー処理の2つの方法:

Promiseは自動的に内部例外をキャッチし、処理のために拒否された応答関数に渡します。

(1)最初のエラー処理

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

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

2番目の方法を使用することをお勧めします。これは、より明確で読みやすく、以前のすべてのエラーをキャプチャできます(Nをキャプチャしてからコールバックエラーをキャプチャできます)。

7、約束の使用法

(1)一般的な使用法:

非同期操作とタイマーが組み合わされます。タイマーが最初にトリガーされた場合、それはタイムアウトと見なされ、ユーザーに通知されます。

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

(2)実際の使用法

コールバックはPromiseとしてパッケージ化されており、2つの明らかな利点があります。

  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