promiseチェーン呼び出しの各種使用シーン

40722 ワード

私たちは通常コードを開発していますが、リターン関数がネストされたコールバック関数の場合には、次のステップの動作は前のステップの操作に依存して非同期の結果を返します.栗を挙げて、私達はセットTimeout関数を使って回転関数をシミュレーションします.
setTimeout(function(){
    setTimeout(function(){
        setTimeout(function(){
            ...
        },100)
    },100)
},100)
このような入れ子の一つ二つはいいです.入れ子が多すぎると、コードを書いている人は頭が痛くなり、コードを見ている人は頭が痛くなります.結果は災難的です.この問題を解決するために、es 6は私達のためにPromiseを導入しました.
プロミス文法をネットで紹介する文章が多いですが、ここではもう一つの角度から、さまざまな場面を使ってプロモーションを利用する方法を教えます.
1,基本的な使い方このシーンでは最もよく使われている状況を紹介します.つまり、1階のリピートネストの場合だけです.
new Promise(function(resolve, reject){
    setTimeout(function(){
        console.log('time ok')
        resolve('return value')
    }, 100)
}).then(function(value){
    console.log(value)
},function(err){
    console.log(err)
})
console.log('end')
/**
    :

end
time ok
return value
*/
このシーンはプロミスの基本的な使い方です.初心者に続きを見てもらうために、プロミセの基本概念を紹介します.
  • Promiseオブジェクトは、3つの状態があります.reolved(完了)、pending(進行中)、reject(失敗)
  • Promise初期化時にはコールバック関数が必要です.初期化が完了すると、このコールバック関数はすぐに実行されます.このときPromiseオブジェクトの状態はpending
  • です.
  • Promise初期化時に出入りするコールバック関数は二つの形があり、第一の形はreject関数であり、第二の行参はreject関数である.resove関数は、現在のPromiseオブジェクトの状態をpendingからresovedに変えることができます.reject関数は、現在のPromiseオブジェクトの状態をpendingからreject
  • に変えることができる.
  • Promiseオブジェクトのthen関数には、2つのパラメータがあり、最初のパラメータは1つのコールバック関数であり、Promiseオブジェクトがpendingからresolovedに変化したときに実行され、コールバック関数のイメージはPromise内部でresove関数を通して伝えられた値であり、上述の例では、「return value」はこのように伝えられている.二つ目のパラメータも一つのコールバック関数であり、Promiseオブジェクトがpendingからrejectに変更されたときに実行され、コールバック関数のイメージはPromiseオブジェクト内部にreject関数を介して渡された値であり、二つ目のパラメータは省略されます.
  • 2,複数のネスト、チェーン呼び出しPromiseの発生は優雅な問題解決のために、どのように文章の冒頭に書かれた災害的な書き方をPromiseで書くのですか?直接コード:
    new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log('time ok')
            resolve('value 1')
        }, 100)
    }).then(function(value){
        return new Promise(function(resolve, reject){
            setTimeout(function(){
                console.log('    :'+ value)
                resolve('value 2')
            }, 400)
        })
    }).then(function(value){
        return new Promise(function(resolve, reject){
            setTimeout(function(){
                console.log('    :'+ value)
                resolve('value 3')
            }, 200)
        })
    }).then(function(value){
        console.log('    :'+ value)
    })
    console.log('end')
    /**
        :
    
    end
    time ok
        :value 1
        :value 2
        :value 3
    */
    
    setTimeout関数のタイミングの時間の長さに関係なく、関数は厳密に上から下までの順序で実行されています.また多くのフィードバックがあれば、チェーン式の次にthenを書いてもいいです.このように、以前のnよりもネストされた書き方は読みやすく、維持しやすいです.
    then関数は新しいPromiseオブジェクトに戻ります.このPromiseオブジェクトは自分でPromiseを通してnewに来ます.上の例のようにPromise.reolve()やPromise.reject()で構成できます.手動で返さなくてもいいです.then関数も自動的にPromiseオブジェクトに戻ります.まず次のコードを見ます.
    var p1 = new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log('time ok')
            resolve('value 1')
        }, 100)
    })
    var p2 = p1.then(function(value){
        console.log('    :' + value)
    })
    console.log('p2:' + p2)
    var p3 = p2.then(function(value){
        console.log('suc:' + value)
    },function(err){
        console.log('fail:' + err)
    })
    console.log('p1 p2    :' + (p1 == p2))
    console.log('p2 p3    :' + (p2 == p3))
    /**
        :
    
    p2:[object Promise]
    false
    false
    time ok
    suc:undefined
    */
    
    実行結果の両方の判断結果がfalseであることから、then関数が戻ってきたPromiseは元のPromiseと同じオブジェクトを指していないことが分かります.最後の出力が「suc:undefined」であることから、p 2のthen関数は何も返されていないが、then関数も自動的にPromise.resove()オブジェクトに戻ります.
    次のコードを見ます.
    new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('value1')
        },100)
    }).then(function(value){
        console.log('    :' + value)
        return Promise.resolve('value2')
    }).then(function(value){
        console.log('    :' + value)
        return 'value3'
    }).then(function(value){
        console.log('    :' + value)
        return Promise.reject('fail')
    }).then(null, function(err){
        console.log('  :' + err)
    })
    console.log('end')
    /**
        :
    
    end
        :value1
        :value2
        :value3
      :fail
    */
    
  • Promise.resove(「suc」)はnew Promise(resove=>resove(「suc」)
  • と同じです.
  • Promise.reject(“fail”)はnew Promiseに等しい.
  • then関数の2つのコールバック関数パラメータのうち、return objectはreturn Promise.resoliveに相当し、次のthenでthen関数の最初のResoliveのコールバック関数
  • をトリガする.
    3、チェーン呼び出しで異常を捕捉するとPromiseオブジェクトのcatch関数でチェーン関数全体のエラーを捕獲できます.catch(function){}関数はthen(null,function){}に相当し、Promiseオブジェクトにも戻ります.チェーンコール中にエラーが発生したら、ずっと下の階に投げます.catchまたはthen関数のreject関数があると知っています.このエラーを捕まえました.これからもrejectを実行します.さもなければ、ずっとrejectを続けます.
    new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log('time ok')
            resolve('value 1')
        }, 100)
    }).then(function(value){
        return new Promise(function(resolve, reject){
            setTimeout(function(){
                console.log('1    :'+ value)
                resolve('value 2')
            }, 400)
        })
    }).then(function(value){
        return new Promise(function(resolve, reject){      
            setTimeout(function(){
                console.log('2    :'+ value)
                resolve('value 3')
            }, 200)
            new kk()
            reject('wrong1')
        })
    }).then(function(value){
        console.log('3    :'+ value)
    }).then(function(value){
        console.log('4    :'+ value)
    },function(err){
        console.log('2    :'+ err)
    }).catch(function(err){
        console.log('catch:' + err)
    }).then(function(value){
        console.log('5    :'+ value)
    })
    console.log('end')
    /**
        :
    
    end
    time ok
    1    :value 1
    2    :ReferenceError: kk is not defined
    5    :undefined
    2    :value 2
    */
    
    実行結果からわかるように、「3受信パラメータ」と「4受信パラメータ」の2つのconsoneは、resoliveエコーに書き込まれています.「2受信エラー」がこのエラーに捉えられて、後の「5受け入れパラメータ」が実行されるまでは、実行されません.上記の例では、「2受信エラー」のrejectコール関数を削除すると、エラーはcatchに4を捕獲し、複数のコールバック関数を成功させて、後のコードを実行します.私たちは開発過程で、たまにあるセグメントコードが二つまたは二つ以上のコールバック関数に依存した結果、実行できます.このような状況はPromiseを使っても同様に適任できます.
    let p1 = new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve('value 1')
        },100)
    })
    let p2 = new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve('value 2')
        },400)
    })
    let p3 = new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve('value 3')
        },100)
    })
    Promise.all([p1, p2, p3]).then(function(results){
        console.log('    :' + results)
    },function(errs){
        console.log(err)
    })
    console.log('end')
    /**
        :
    
    end
        :value 1,value 2,value 3
    */
    
    Promise.allは、複数の前置コール関数が完了してから、then()の操作を実行するのに適しています.
    5、複数のコールバック関数のうち、一つだけが実行に成功したら、後のコードを実行するということは、コードの前の複数のコールバック関数が実行に成功したら実行を開始するということです.このような状況は普段あまり見られないです.下記のコードで調べてみます.
    let p1 = new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log('    :value 1')
            resolve('value 1')
        },100)
    })
    let p2 = new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log('    :value 2')
            resolve('value 2')
        },400)
    })
    let p3 = new Promise(function(resolve, reject){
        setTimeout(function(){
            console.log('    :value 3')
            resolve('value 3')
        },200)
    })
    Promise.race([p1, p2, p3]).then(function(results){
        console.log('    :' + results)
    },function(errs){
        console.log(err)
    })
    console.log('end')
    /**
        :
    
    end
        :value 1
        :value 1
        :value 3
        :value 2
    */
    
    実行結果から、value 1のsettimeout時間が一番短いので、最初に結果のresoveを外に出して、後のthen関数のresoveフィードバックがすぐに実行され、パラメータを受信することができます.その後、二つのPromiseがタイマーの時間の長さによってそれぞれ結果を出力します.then関数をトリガするresoliveではないです.
    Promise.race()の役割は複数のコールバックを同時に実行することでもあり、allとは違って、一つのコールバックが成功したら、後のthen関数を呼び出します.成功したコールバックは、then()をトリガしなくなります.