アウトライン
JavaScriptの世界では、すべてのコードは、シングルスレッドの実行です。
そのため、すべてのネットワーク運用を引き起こし、この「欠陥」、の、ブラウザのイベントJavaScriptは、非同期で実行されなければなりません。
AJAXは、典型的な非同期操作です。
コールバック関数success(request.responseText)
とはfail(request.status)
、正常にAJAX操作を書きましたが、良い見ていませんが、また、コードの再利用を助長されていません。
より良い方法はありますか?たとえば、次のように書かれて:
VaRのアヤックス= ajaxGet( 'のhttp:// ...' ); ajax.ifSuccess(成功) .ifFail(失敗)。
AJAXロジックの最初の均一な実装、将来のある時点で呼び出して、成功または失敗の結果によると、その後、結果をどのように扱うかを気にしないsuccess
関数やfail
機能。これは、オブジェクトの「未来の実現にコミットは」約束はJavaScriptでオブジェクトと呼ばれます。
例
私たちは、約束の簡単な例を見て:0と2の間の乱数を生成し、1未満ならば、そうでない場合は、一定期間後の成功に戻るのを待っていると、失敗します。
機能試験(解決、リジェクト){ VARのタイムアウト= Math.random()* 2 。 console.log( 'にタイムアウトを設定:' + TIMEOUT + '秒' ); setTimeoutメソッド(関数(){ 場合(タイムアウト<1 ){ はconsole.log( 'コール決意()...' ); (解決 '200 OK' ); } 他{ はconsole.log(「コールが(拒否).. 。」;) (リジェクト '+タイムアウト+ '秒でタイムアウト'' ); } }、)。
図から分かるように、test()
独自のロジックのみに関心の機能は、特定の気にしないresolve
し、reject
結果を処理します。
関数の実行で、我々はそれを実行することを約束オブジェクトを使用することができ、およびいくつか将来の時点での結果の成功または失敗:
VaRの P1 = 新しい約束(テスト); VaRの P2 = p1.then(関数(結果){ にconsole.log( '成功' + 結果); }); VAR P3 = P2。キャッチ(関数(理由){ にconsole.log( '失败' + 理由); });
プロミスオブジェクトをつなぎ合わせすることができ、上記のコードは、に簡略化することができます。
新しいプロミス(テスト).then(関数(結果){ にconsole.log( '成功' + もたらします); })。キャッチ(関数(理由){ にconsole.log( '失败' + 理由); });
最大の利点は、非同期実行の過程で見られる約束、実行コードと明確に分離された処理結果のコード:
Promise.all()これら2つのタスクが並列に実行することができます
VaRの P1 = 新しい新しいプロミス(関数(解決、拒否){ のsetTimeoutは(解決 500 'のPL' ); }); VARの P2 = 新しい新しいプロミス(関数(解決、拒否){ たsetTimeout(解決、 600、 'P2' ); }); // 同時にP1およびP2を実行し、それらが次に終了した後に行われる: Promise.all([P1、P2])を(関数(結果){ にconsole.log(結果); //を得ます配列:[ 'P1の'、 'P2'] })。
Promise.race()複数の非同期タスクフォールトトレラントするだけ返される最初の結果を取得する必要があります。
VaRの P1 = 新しいプロミス(関数(解決、リジェクト){ たsetTimeout(決意、 500、 'P1' ); }); VaRの P2 = 新しいプロミス(関数(解決、リジェクト){ たsetTimeout(決意、 600、 'P2' ); }); Promise.race([P1、P2])を(関数(結果){ にconsole.log(結果); // 'P1' })。
プロミス状態
(進行中の)保留、成就(成功)と拒否(失敗):約束の非同期操作は3つの状態があります。非同期動作の結果に加えて、他の操作がその状態を変更することはできません。
成就と保留状態の変更を拒否になるために保留中の変更から:オブジェクトのみをお約束します。限りで満たされ、拒否として、状態はそれが解決されて変更されていません(確定)。
その後、方法
この方法は、パラメータとしての二つの機能を受け取り、最初のパラメータは、成功の約束、2番目のパラメータはプロミスが失敗したときにコールバックされ、2つのだけの機能があるだろうが呼び出されるコールバックです。
現在実行中のJavaScriptのイベントキューが完了する前に、コールバック関数が呼び出されることはありません。
することで 、どんな.thenフォームコールバック関数を追加していない、それが呼び出されます。
コールバック関数VS約束
之前大家解决异步事件都是用回调函数去解决,但是回调函数写异步会出现一些问题,
回调地狱的问题。
那么promise就是一种新的处理异步的方法,可以完美的解决回调函数处理异步带来的问题(回调地狱问题)。
其实promise就是异步操作的方法,就像之前的定时器一样,看到定时器就知道这是异步操作,同样,看到promise就知道这个是异步操作。
VaRののsayHello = 関数(名前、コールバック){ たsetTimeout(関数(){ にconsole.log(名前); コールバック(); }、 1000年)。 } のsayHello( "第一"、関数(){ のsayHello( "第二"、関数(){ のsayHello( "第3"、関数(){ にconsole.log( "終了" ) );} }); }); // 输出:第二第三端
プロミスオブジェクト、ジェネレータ関数、非同期機能:のようなコールバック地獄を解決するために多くの方法がありますが、
コールバック地獄を解決するために、オブジェクトを約束
VARのsayHello = 関数(名前){ 戻り 、新たな新プロミス(関数(解決、拒否){ たsetTimeout(関数(){ にconsole.log(名前) 解決(); // 実行解決()関数の非同期操作が行われた後 } 1000 ); }); } のsayHello( "第一")を(関数(){ 戻りのsayHello( "秒"); //は依然としてプロミスオブジェクトを返す 。})を(関数(){ 戻り THIRD」(のsayHelloを" ); })を(関数(){ console.log( '終了' )。 })。キャッチ(関数(ERR){ にconsole.log(ERR); })