この記事では、参考値の高いjQueryのdeferredオブジェクトとextendメソッドを中心に紹介します。以下のエディターで見てみましょう。皆さんのお役に立てれば幸いです。
1 遅延オブジェクト
遅延オブジェクトは、jQuery バージョン 1.5.0 から導入された機能である jQuery のコールバック関数ソリューションです。
遅延オブジェクトのメソッド
(1) $.Deferred() は遅延オブジェクトを生成します。
(2) deferred.done() は操作が成功したときのコールバック関数を指定します
(3) deferred.fail() は操作が失敗したときのコールバック関数を指定します
(4) deferred.promise() は when を返しますパラメーターはありません。パラメーターを受け入れるときに実行ステータスを変更できない新しい遅延オブジェクト。パラメーター オブジェクトに遅延インターフェイスをデプロイするために使用されます。
(5) deferred.resolve() 遅延オブジェクトの実行ステータスを手動で「Completed」に変更し、done() メソッドを即座にトリガーします。
(6) deferred.reject() このメソッドは deferred.resolve() の逆です。呼び出された後、遅延オブジェクトの実行ステータスは「失敗」に変更され、したがって、fail() メソッドが即座にトリガーされます。
(7) $.when() は複数の操作のコールバック関数を指定します。
これらのメソッドに加えて、遅延オブジェクトには 2 つの重要なメソッドもありますが、上記のチュートリアルでは説明されていません。
(8) deferred.then()
手間を省くために、done()とfail()を一緒に書くことができます。これがthen()メソッドです。
$.when($.ajax( "/main.php" )) .then(successFunc, failureFunc );
then() に 2 つのパラメーターがある場合、最初のパラメーターは Done() メソッドのコールバック関数であり、2 番目のパラメーターは、fail() メソッドのコールバック メソッドです。 then() にパラメータが 1 つしかない場合、done() と同等です。
(9) deferred.always()
このメソッドはコールバック関数の指定にも使用され、その機能は deferred.resolve() と deferred.reject() のどちらが呼び出されても常に実行されることです。終わり。
$.ajax( "test.html" ) .always( function() { alert("已执行!");} );
何かやってみよう
1) ajax操作のチェーン記述方法
まず、jQueryのajax操作の従来の記述方法を確認してください:
$.ajax({ url: "test.html", success: function(){ alert("哈哈,成功了!"); }, error:function(){ alert("出错啦!"); } });
上記のコードでは、$.ajax()はオブジェクトパラメータを受け入れます。 2 つのメソッドが含まれます。success メソッドは操作が成功した後のコールバック関数を指定し、error メソッドは操作が失敗した後のコールバック関数を指定します。
$.ajax() 操作が完了すると、1.5.0 より前のバージョンの jQuery を使用している場合は XHR オブジェクトが返され、1.5.0 より高いバージョンの場合はチェーン操作を実行できません。 deferred が返されます。 オブジェクトは連鎖させることができます。
遅延オブジェクトを取得したら、次のように記述できます
$.ajax("test.html") .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
done() は上記のコードに相当し、success メソッドに相当し、fail() は error メソッドに相当します。チェーンライティング方式の採用により、コードの可読性が大幅に向上しました。
2) 同じ操作に対して複数のコールバック関数を指定します
遅延オブジェクトの大きな利点の 1 つは、複数のコールバック関数を自由に追加できることです。
上記のコードを例にとると、ajax 操作が成功した後、元のコールバック関数に加えて、別のコールバック関数も実行したい場合、どうすればよいですか?
とても簡単なので、最後に追加するだけです。
$.ajax("test.html") .done(function(){ alert("哈哈,成功了!");} ) .fail(function(){ alert("出错啦!"); } ) .done(function(){ alert("第二个回调函数!");} );
コールバック関数は好きなだけ追加でき、追加された順序で実行されます。
3) 複数の操作に対してコールバック関数を指定する
遅延オブジェクトのもう 1 つの大きな利点は、従来の記述では不可能だった複数のイベントに対してコールバック関数を指定できることです。
新しいメソッド $.when() を使用する以下のコードを見てください:
$.when($.ajax("test1.html"), $.ajax("test2.html")) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
このコードの意味は、最初に 2 つの操作 $.ajax("test1.html") と $.ajax (" test2.html")、すべてが成功した場合は、done() で指定されたコールバック関数を実行します。一方または両方が失敗した場合は、fail() で指定されたコールバック関数を実行します。
4) 一般的な操作のためのコールバック関数インターフェース (パート 1)
遅延オブジェクトの最大の利点は、このコールバック関数インターフェースのセットを ajax 操作からすべての操作に拡張することです。つまり、ajax 操作かローカル操作か、非同期操作か同期操作かに関係なく、どの操作でも遅延オブジェクトのさまざまなメソッドを使用してコールバック関数を指定できます。
具体的な例を見てみましょう。時間のかかる操作待機があるとします。
var wait = function(){ var tasks = function(){ alert("执行完毕!"); }; setTimeout(tasks,5000); };
そのコールバック関数を指定します。どうすればよいでしょうか?
当然$.when():
$.when(wait()) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
を使えばいいと思うでしょうが、このように書くとdone()メソッドが即実行されてしまいコールバック関数として機能しません。その理由は、$.when() のパラメーターは遅延オブジェクトのみであるため、wait() を書き直す必要があるためです。
var dtd = $.Deferred(); // 新建一个deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd; };
これで、wait() 関数は遅延オブジェクトを返すため、チェーン操作を追加できます。
$.when(wait(dtd)) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
wait() 関数の実行が終了すると、done() メソッドで指定されたコールバック関数が自動的に実行されます。
5) deferred.resolve() メソッドと deferred.reject() メソッド
jQuery では、遅延オブジェクトには 3 つの実行状態 (未完了、完了、失敗) があると規定しています。実行ステータスが「完了」(解決済み) の場合、遅延オブジェクトは、done() メソッドで指定されたコールバック関数をすぐに呼び出します。実行ステータスが「失敗」の場合、fail() メソッドで指定されたコールバック関数が呼び出されます。実行ステータスが「失敗」「完了」の場合は、そのまま待機するか、progress() メソッド (jQuery 1.7 バージョンで追加) で指定されたコールバック関数を呼び出します。
前面部分的ajax操作时,deferred对象会根据返回结果,自动改变自身的执行状态;但是,在wait()函数中,这个执行状态必须由程序员手动指定。dtd.resolve()的意思是,将dtd对象的执行状态从"未完成"改为"已完成",从而触发done()方法。
类似的,还存在一个deferred.reject()方法,作用是将dtd对象的执行状态从"未完成"改为"已失败",从而触发fail()方法。
var dtd = $.Deferred(); // 新建一个Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.reject(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd; }; $.when(wait(dtd)) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
6)deferred.promise()方法
上面这种写法,还是有问题。那就是dtd是一个全局对象,所以它的执行状态可以从外部改变。
请看下面的代码:
var dtd = $.Deferred(); // 新建一个Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd; }; $.when(wait(dtd)) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); dtd.resolve();
我在代码的尾部加了一行dtd.resolve(),这就改变了dtd对象的执行状态,因此导致done()方法立刻执行,跳出"哈哈,成功了!"的提示框,等5秒之后再跳出"执行完毕!"的提示框。
为了避免这种情况,jQuery提供了deferred.promise()方法。它的作用是,在原来的deferred对象上返回另一个deferred对象,后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和
reject()方法),从而使得执行状态不能被改变。
请看下面的代码:
var dtd = $.Deferred(); // 新建一个Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象 }; var d = wait(dtd); // 新建一个d对象,改为对这个对象进行操作 $.when(d) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); d.resolve(); // 此时,这个语句是无效的
在上面的这段代码中,wait()函数返回的是promise对象。然后,我们把回调函数绑定在这个对象上面,而不是原来的deferred对象上面。这样的好处是,无法改变这个对象的执行状态,要想改变执行状态,只能操作原来的deferred对象。
不过,更好的写法是将dtd对象变成wait()函数的内部对象。
var wait = function(dtd){ var dtd = $.Deferred(); //在函数内部,新建一个Deferred对象 var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象 }; $.when(wait()) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
7)普通操作的回调函数接口(中)
另一种防止执行状态被外部改变的方法,是使用deferred对象的建构函数$.Deferred()。
这时,wait函数还是保持不变,我们直接把它传入$.Deferred():
$.Deferred(wait) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
jQuery规定,$.Deferred()可以接受一个函数名(注意,是函数名)作为参数,$.Deferred()所生成的deferred对象将作为这个函数的默认参数。
8)普通操作的回调函数接口(下)
除了上面两种方法以外,我们还可以直接在wait对象上部署deferred接口。
var dtd = $.Deferred(); // 生成Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); }; dtd.promise(wait); wait.done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); wait(dtd);
这里的关键是dtd.promise(wait)这一行,它的作用就是在wait对象上部署Deferred接口。正是因为有了这一行,后面才能直接在wait上面调用done()和fail()。
2 extend方法
JQuery的extend扩展方法:
Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解。
1)Jquery的扩展方法原型是:
extend(dest,src1,src2,src3...);
它的含义是将src1,src2,src3...合并到dest中,返回值为合并后的dest,由此可以看出该方法合并后,是修改了dest的结构的。如果想要得到合并的结果却又不想修改dest的结构,可以如下使用:
var newSrc=$.extend({},src1,src2,src3...)//也就是将"{}"作为dest参数。
这样就可以将src1,src2,src3...进行合并,然后将合并结果返回给newSrc了。如下例:
var result=$.extend({},{name:"Tom",age:21},{name:"Jerry",sex:"Boy"})
那么合并后的结果
result={name:"Jerry",age:21,sex:"Boy"}
也就是说后面的参数如果和前面的参数存在相同的名称,那么后面的会覆盖前面的参数值。
2)省略dest参数
上述的extend方法原型中的dest参数是可以省略的,如果省略了,则该方法就只能有一个src参数,而且是将该src合并到调用extend方法的对象中去,如:
$.extend(src)
该方法就是将src合并到jquery的全局对象中去,如:
$.extend({ hello:function(){alert('hello');} });
就是将hello方法合并到jquery的全局对象中。
$.fn.extend(src)
该方法将src合并到jquery的实例对象中去,如:
$.fn.extend({ hello:function(){alert('hello');} });
就是将hello方法合并到jquery的实例对象中。
下面例举几个常用的扩展实例:
$.extend({net:{}});
这是在jquery全局对象中扩展一个net命名空间。
$.extend($.net,{ hello:function(){alert('hello');} })
这是将hello方法扩展到之前扩展的Jquery的net命名空间中去。
3)Jquery的extend方法还有一个重载原型:
extend(boolean,dest,src1,src2,src3...)
第一个参数boolean代表是否进行深度拷贝,其余参数和前面介绍的一致,什么叫深层拷贝,我们看一个例子:
var result=$.extend( true, {}, { name: "John", location: {city: "Boston",county:"USA"} }, { last: "Resig", location: {state: "MA",county:"China"} } );
我们可以看出src1中嵌套子对象location:{city:"Boston"},src2中也嵌套子对象location:{state:"MA"},第一个深度拷贝参数为true,那么合并后的结果就是:
result={name:"John",last:"Resig", location:{city:"Boston",state:"MA",county:"China"}}
也就是说它会将src中的嵌套子对象也进行合并,而如果第一个参数boolean为false,我们看看合并的结果是什么,如下:
var result=$.extend( false, {}, { name: "John", location:{city: "Boston",county:"USA"} }, { last: "Resig", location: {state: "MA",county:"China"} } );
那么合并后的结果就是:
result={name:"John",last:"Resig",location:{state:"MA",county:"China"}}
以上是网上看到的两篇分别对jQuery中的deferred对象和extend方法的介绍,感觉比较详细而且容易理解,所以把它们整理到一起与大家分享!
相关推荐:
$.Deferred(),for循环内异步请求问题的解决方法
以上がjQueryの遅延オブジェクトとextendの違いを詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。