ホームページ  >  記事  >  ウェブフロントエンド  >  jQueryのPromiseの正しい使い方

jQueryのPromiseの正しい使い方

小云云
小云云オリジナル
2018-01-26 10:58:302239ブラウズ

jQuery の Promise の使用方法についてどのくらい知っていますか?この記事では主に jQuery の Promise の正しい使い方を紹介し、皆さんのお役に立てれば幸いです。

以前 ES6 の Promise オブジェクトについて学習したので、jQuery の Deferred オブジェクトである jQuery の Promise を見てみましょう。

まずブラウザのコンソールを開きます。


<script>
  var defer = $.Deferred();
  console.log(defer);
</script>

動作結果:

は、ES6 の Promise オブジェクトに少し似ています。jQuery の Deferred オブジェクトには、done、fail、always... メソッドだけでなく、resolve、reject、then メソッドもあります。 jQuery は、この Deferred オブジェクトを使用して、非同期操作のコールバック関数を登録し、非同期操作のステータスを変更および転送します。

Deferred で遊ぶ:


<script>
  function runAsync(){
    var defer = $.Deferred();
    //做一些异步操作
    setTimeout(function(){
      console.log(&#39;执行完成&#39;);
      defer.resolve(&#39;异步请求成功之后返回的数据&#39;);
    }, 1000);
    return defer;
  }
  runAsync().then(function(data){
    console.log(data)
  });
</script>

実行後、Deferred オブジェクトの defer インスタンスはパラメータ「非同期リクエストが成功した後に返されるデータ」を then メソッドに返し、resolve メソッドを介して受信および出力します。

ES6 Promise に似ていますが、少し違いがあります。


<script>
  function runAsync(){
    var p = new Promise(function(resolve, reject){
      
      setTimeout(function(){
        console.log(&#39;执行完成&#39;);
        resolve(&#39;异步请求成功之后返回的数据&#39;);
      }, 1000);
    });
    return p;      
  }

  runAsync().then(function(data){
    console.log(data);
  });
</script>

次のことがわかりました。

1. Promise の作成時にパラメーターは渡されません。オブジェクト、パラメーターが渡されます (匿名関数が渡され、この関数には、resolve メソッド、reject

という 2 つのパラメーターもあります)。Promise オブジェクトは内部でsolveメソッドを呼び出します。

説明: Deferred オブジェクト自体にはsolveメソッドがあり、コンストラクター内でresolveメソッドを実行することでPromiseオブジェクトに実行結果のステータスが代入されます。

これには欠点があります: Deferred オブジェクトには独自のsolveメソッドがあるため、Deferredオブジェクトを取得した後はいつでもresolveメソッドを呼び出すことができ、そのステータスを手動で介入できます

<script>
  function runAsync(){
    var defer = $.Deferred();
    //做一些异步操作
    setTimeout(function(){
      console.log(&#39;执行完成&#39;);
      defer.resolve(&#39;异步请求成功之后返回的数据&#39;);
    }, 1000);
    return defer;
  }
   var der = runAsync();
   der.then(function(data){
    console.log(data)
   });
   der.resolve(&#39;在外部结束&#39;); 
</script>

この場合、外部から直接与えることができます。 Deferred はステータスを設定し、「外部で終了」を出力し、1 秒後に「実行完了」を出力します。「非同期リクエストが成功した後に返されたデータ」は出力しません。

明らかに、これは良くありません。非同期リクエストを送信しましたが、データが受信される前に、誰かが外部でリクエストを終了しました。 。 。 。 。 。 。

もちろん、jQuery は間違いなくこの穴を埋めます。 Deferred オブジェクトには Promise メソッドがあります。これは制限された Deferred オブジェクトです

<script>
  function runAsync(){
    var def = $.Deferred();
    //做一些异步操作
    setTimeout(function(){
      console.log(&#39;执行完成&#39;);
      def.resolve(&#39;请求成功之后返回的数据&#39;);
    }, 2000);
    return def.promise(); //就在这里调用
  }
</script>

いわゆる制限された Deferred オブジェクトは、resolve メソッドと拒否メソッドのない Deferred オブジェクトです。このように、Deferred オブジェクトの状態を外部から変更することはできません。

Deferredオブジェクトとdoneとfailの糖衣構文のthenメソッド

ES6のPromise仕様では、thenメソッドは実行完了と実行失敗のコールバックである2つのパラメータを受け入れることがわかっており、jqueryが強化されていますでは、次のように、保留状態のコールバックである 3 番目のパラメーターを受け入れることもできます:

then メソッド: deferred.then( doneFilter [, failFilter ] [, progressFilter ] )

<script>
  function runAsync(){
    var def = $.Deferred();
    //做一些异步操作
    setTimeout(function(){
       var num = Math.ceil(Math.random()*10); //生成1-10的随机数
        if(num<=5){
          def.resolve(num);
        }
        else{
          def.reject(&#39;数字太大了&#39;);
        }
    }, 2000);
    return def.promise(); //就在这里调用
  }

  runAsync().then(function(d){
    console.log("resolve");
    console.log(d);
  },function(d){
    console.log("reject");
    console.log(d);
  })

</script>

Deferred オブジェクトの then メソッドは、チェーン操作を実行することもできます。実行完了と実行失敗のコールバックをそれぞれ指定するために使用される

done、fail 構文シュガーは、次のコードと同等です:

<script>
  function runAsync(){
    var def = $.Deferred();
    //做一些异步操作
    setTimeout(function(){
       var num = Math.ceil(Math.random()*10); //生成1-10的随机数
        if(num<=5){
          def.resolve(num);
        }
        else{
          def.reject(&#39;数字太大了&#39;);
        }
    }, 2000);
    return def.promise(); //就在这里调用
  }

  runAsync().done(function(d){
    console.log("resolve");
    console.log(d);
  }).fail(function(d){
    console.log("reject");
    console.log(d);
  })

</script>


always の使用法

jquery には Deferred オブジェクトもあります実行が完了したか失敗したかに関係なく実行されます。これは、ajax での complete に似ています。

$.whenの使い方

jqueryにはPromiseを実装するための$.whenメソッドもありますが、これはES6のallメソッドと同じ機能を持っており、非同期操作を並行して実行し、結局コールバックを実行します。非同期操作が実行される関数です。ただし、$.when は $.Deferred では定義されていません。$.when という名前を見れば、これが別のメソッドであることがわかります。 ES6 の all パラメータとは少し異なります。次のように、配列ではなく複数の Deferred オブジェクトを受け入れます。最も速い方法に基づいた方法です。そうですね、jqueryには存在しません。

上記は、jquery の Deferred オブジェクトの一般的なメソッドです。

前回の記事と今回の記事では、データ処理に非同期リクエストの代わりにワンタイムタイマーを使用しました。なぜ ajax を使用しないのですか? それは問題があるからではありません。 ここで ajax と Deferred の関係について話したいと思います。


jquery の ajax は制限付きの Deferred オブジェクトを返します。 Deferred オブジェクトであるため、状態を外部から変更することはできません。そのため、上で説明したすべての機能は ajax でも利用できます。たとえば、連鎖呼び出し、複数のリクエストの連続送信:

<script>
 function runAsync(){
    var def = $.Deferred();
    //做一些异步操作
    setTimeout(function(){
       var num = Math.ceil(Math.random()*10); //生成1-10的随机数
       def.resolve(num);  
    }, 2000);
    return def.promise(); //就在这里调用
  }
  $.when(runAsync(), runAsync(), runAsync()) .then(function(data1, data2, data3){
     console.log(&#39;全部执行完成&#39;);
     console.log(data1, data2, data3);
  });
</script>

success、error、complete

これら 3 つのメソッドは、一般的に使用される ajax 構文の糖衣です。


<script>
req1 = function(){
  return $.ajax(/* **** */);
}
req2 = function(){
  return $.ajax(/* **** */);
}
req3 = function(){ 
  return $.ajax(/* **** */);
}
req1().then(req2).then(req3).done(function(){ console.log(&#39;请求发送完毕&#39;); });
</script>
場合によっては、属性として内部的に処理することを好むことがあります。

ajax リクエストの成功、失敗、終了のコールバックをそれぞれ示します。これら 3 つのメソッドと Deferred の間にはどのような関係があるのでしょうか?実際、これは糖衣構文であり、成功は完了に対応し、エラーは失敗に対応し、完了は ajax とのパラメータ名の一貫性を保つためだけです。

概要:

$.Deferred は Promise 仕様を実装し、then、done、fail、always は Deferred オブジェクトのメソッドです。 $.when は複数の非同期タスクを並行して実行するために使用されるグローバル メソッドであり、ES6 のすべてと同じ機能です。 ajax は、制限付きの Deferred オブジェクトを返します。Success、error、および complete は、ajax によって提供される構文上の機能であり、Deferred オブジェクトの Done、Fail、および Always と一致します。

関連する推奨事項:

promsie.allとPromiseの逐次実行の詳細な説明

JSでPromiseを使用して信号機のサンプルコードを実装する(デモ)

Promiseオブジェクトの簡単な使用法について

以上がjQueryのPromiseの正しい使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。