【JavaScript】Promise教程、Promiseの使用.


重要な声明:この文章は著者個人のこの観点に対する理解と表現を表しています.読者は閲覧時に自分の意見を持って討論してください.
本論文の原文:【JavaScript】Promise教程、Promiseの使用.この文章の更新は直ちに原文の住所までブラウズすることを提案しません.
PromiseはES 6が加入する特性で、非同期タスクをより合理的かつ強力にします.多くの人が使い始めました.私たちもじっと見ていてはいけません.技術的なポイントも財布に入れなければなりません.
初物を賞味する
正式に紹介する前に、まずPromiseを見てみます.普通はどんな体験ですか?次のカラムを使用します.
// 1
new Promise(function(resolve, reject) {
    try{
        var response = ajaxPost('https://www.baidu.com', {key: "Microanswer"})
        resolve(response)
    } catch (err) {
        reject(err)
    }

// 2
}).then(function(response) {
    if (response.code === 200) {
        return buildResult(response.data)
    } else {
        throw new Error("    。")
    }

// 3
}).then(function (data) {
    render(data)

// 4
}).catch(function (err) {
    renderErr(err)
})
上記のコードは一回の要求を完了し、結果を界面にレンダリングします.コードの表示から、要求から表示までを3ステップに分け、4ステップ目はエラーの結果として表示されます.
第1ステップ:Postリクエストを送信します.try...catchを使って異常捕獲することで、ネットワークの円滑化による問題を捉えることができます.
第二ステップ:解析した要求は内容に戻り、内容が正しければ結果を構築する.そうでないとエラーが発生します.
ステップ3:データをレンダリングします.
異常処理:このステップは最後の最後にあります.前のステップでもエラーが発生したら直接異常処理を行います.
非同期タスクの終了後の論理の正常な終了を保証するために過去に同調関数を使用した方式が現れていないことが分かりやすく、逆に次のthenが後のチェーンで一緒にいる.これはコード実行プロセスにおける直感的な体験をもたらしたに違いない.
一、Promiseオブジェクトの作成
Promiseオブジェクトの作成方法には、構造関数によって提供される静的な方法の2つがあります.
1、コンストラクタによる
このような方法では、過去のコールバック関数を使って達成された非同期のタスクに適合することができます.典型的な作成方法を以下に示す.
var promise = new Promise(function (resolve, reject) {
    resolve("Hello Promise!")
})
このコードは非常に簡単なプロミセオブジェクトを構成しています.その意味が分からないなら、詳しく説明します.まずPromise構造関数自体に目を向けます.これは非常に単純なコンストラクタであり、Promiseオブジェクトの構成に成功するには、一つのパラメータを提供する必要があります.このパラメータはFunctionタイプのものです.promiseが実行されると、この方法を呼び出して、二つのパラメータが入ってきます.それらはそれぞれreolveとrejectです.
1)、レスリングパラメータ
あなたが転送したFunctionが完了したら、結果を生成しなければなりません.Promiseの正確な実行のために、Promiseに教えてください.あなたの実行結果は正しいですか?それとも間違っていますか?resoliveは、実際には、正しい結果が出たら、resolve()を呼び出して実行しても良いし、正しい結果が得られます.パラメータがなくても良いです.パラメータがあれば、resolve("Jack")などのパラメータを入れてもいいです.これは正しいタスクを完了したマークに相当し、結果を伝えていきます.このプロミセの次のthenの中に、あなたが入ってきた"Jack"があります.たとえば:
var promise = new Promise(function (resolve, reject) {
    resolve("Jack");
})
promise.then(function (result) {
    console.log(result) //   :Jack
})
2)、rejectパラメータ
どんな任務でも、特に非同期の時間のかかる任務では、間違いは避けられない.したがって、Funct実行中にエラーが発生した場合、rejectはPromiseにエラーを伝えることを許可します.もしあなたのPromiseの後ろにたくさんのthenタスクノードがあったら、これらのノードは実行されなくなります.Promiseはずっと次のcatch方法を探しています.見つからなかったら、エラーが発生します.捕獲されていない異常なxxxを発見します.以下に典型的なエラーシーンを示します.
var promise = new Promise(function (resolve, reject) {
    reject(new Error("   "));
})
promise.then(function (result) {
    console.log(result) //     
}).catch(function (result) {
    console.log(result) //   :   
})
最初のコンストラクタの中で、直接rejectを使ってエラーを指定しました.Promiseはエラーを見つけて、最後にcatchを探し始めました.その後、catchは直ちに実行して、エラー情報を印刷しました.
コンストラクタを通してpromiseを作成した事例は、reolveとrejectを提供することによって、以前の非同期タスク(コールバック方法)を完全に互換させた基本的な理解が得られています.
例えば、Promiseを使用する前に、ネットワーク要求方法を開発しました.リクエスト結果を得るためにコールバック関数を使用しました.
function post(url, param, callback) {
    $.ajax({
        ...,
        success: function (res) {callback(null, res)}
        error: function (err) {callback(err, null)}
    })
}

//     
post("https://www.baidu.com", {key: "Jack"}, function (err, res) {
    //       。
})
Promiseが追加されました.このようにコールバック関数を使わないでください.結果を得ることができます.Promiseコンストラクターを使って一回のパッケージを作ることができます.
function postByPromise(url, param) {
   return new Promise(function (resolve, reject) {
       post(url, param, function (err, res) {
            if (err) reject(err) else resolve(res)
       })
   })
}

//   
postByPromise("https://www.baidu.com", {key: "Jack"})
    .then(function (res) {
        //       。
    })
上記のコードにより、本来はコールバック関数によって実現されていた非同期タスクが、Promiseを用いて完全にパッケージ化され、チェーン式の呼び出し方式が実現されることがわかる.
2、静的方法による作成
静的方法によりpromiseオブジェクトを作成することもまた、thenの後方に止まらないチェーン呼び出しを使用することができる.作成するのはもっと簡単で、あなたが少しのロジックを実現する必要さえないなら、プロミセオブジェクトを作成することができます.たとえば:
var promise = Promise.resolve("Jack");
promise.then(function (result) {
    console.log(result) //   :Jack
})
とても簡単ですね.このように作成されたpromiseオブジェクトは正確なpromiseオブジェクトとして明確にマークされています.最初のcatchは永遠に実行されません.正確なpromiseオブジェクトを作成する以外に、Promiseは間違ったpromiseオブジェクトを作成する方法を提供します.
var promise = Promise.reject("   ");
promise.catch(function (err) {
    console.log(err); //   :   
})
二、さらにPromiseを使う
上の内容を知ると、さらにPromiseを使って任務を遂行することができます.まだ多くの特性がありますが、上に紹介されていないので、コードに合わせて説明します.
1、エラーが発生したら続ける
上のコードの中で、catchコードはいつも最後になりますが、必ずタスクの実行手順ごとに最後のエラー捕獲だけが必要ではなく、途中で捕獲することが多いです.そして、エラーに対する処理もあります.次の列を示します.
Promise.resolve()
    .then(function () {
        return "name"                //   
    }).then(function (name) {
        return Promise.reject("  ") //        
    }).then(function (resut) {
        return "age"                  //    ,         。
    }).catch(function (err) {
        console.log(err)              //   ,      。
        return "     "
    }).then(function (msg) {
        comsole.log(msg)              //   ,                msg
    })
上記のコードの中で、途中でエラープロミスを構築して戻ってきました.その後、エラーがあったら、後続のthenを実行しません.続いているthenが実行されていないことが分かります.続いて、catchが発見され、このcatchにエラーを与えて実行し、catchが実行された後に文字列を返しました.Promiseは、エラーはすでに処理されたと考えて、次のthenを実行します.
2、複数のPromise
もしこのような要求があるならば、今3つの要求を同時に送りますが、業務ロジックはすべての要求が完了したら行わなければなりません.この場合、伝統的なコール方式で処理すれば、必ず多くのコードを書いてメンテナンスに行く必要があります.3つの要求が全部完了しました.今はPromiseがあれば、この需要を簡単に完成できます.
var req1 = postByPromise("/xxx", {...})
var req2 = postByPromise("/zzz", {...})
var req3 = postByPromise("/yyy", {...})

//       
Promise.all([req1, req2, req3])
    .then(function (result) {
        var result1 = result.result1;
        var result2 = result.result2;
        var result3 = result.result3;
        //         ,       。
    })
3、エラーが発生したらやり直します
よくネットワーク要求が失敗しましたが、再要求が正常になりました.これは私たちが失敗したメカニズムを作って、ミスを実行するたびにやり直して、最大回数を指定し、回数を超えると最終的にエラーが発生します.
function postByPromiseTryCount(url, param, maxTryCount) {
    var tryCount = 0

    function d0(url, param) {
        return postByPromise(url, param).catch(function (err) {

            //           ,      。
            if (++tryCount < maxTryCount) {
                return d0(url, param)
            } else {
                return Promise.reject(err)
            }
        })
    }

    return d0(url, param)
}
上記のpostByPromiseTryCount方法は、postByPromiseメソッドのパッケージ化であり、失敗自動再試行機能をサポートしています.
4、注意事項
Promiseは使いやすいですが、使い方に問題があります.使用中に発生した問題を以下に羅列します.
  • for循環を結合して使う場合、フロントエンドの場合は、パッケージのエルゴードメソッドを使用してください.
  • Promise内で実行されるタスクはすべて非同期です.前のコードで先に実行されるわけではありませんが、promise外部のコードは常に先に実行されます.
  • 各then方法は2つのパラメータを渡すことができます.最初は正しい時に実行されます.第二のエラー時に実行されます.catch関数を書かずにエラートラッピング関数を第二のパラメータに置くことができます.
  • 各then方法は新たなpromiseオブジェクトを返します.戻り値がなくても、値が空のpromiseのオブジェクトを返します.つまり、あなたもthenを続けることができます.
  • です.ですから、マークを間違えたら、間違ったpromiseを返してもいいです.直接throwエラーメッセージを返してもいいです.
  • 最後に書いてください
    この文章はPromiseの基本的な初級の使い方だけを紹介しました.まだ多くの高級な使い方が紹介されていません.もっと深く理解したいです.ここをクリックして調べてください.