Rumah > hujung hadapan web > tutorial js > Penjelasan terperinci tentang jQuery.deferred object usage_jquery

Penjelasan terperinci tentang jQuery.deferred object usage_jquery

WBOY
Lepaskan: 2016-05-16 15:10:20
asal
1186 orang telah melayarinya

1
Sebelum jQuery 1.5, jika berbilang operasi Ajax diperlukan, kami biasanya menggunakan dua kaedah berikut:

1).Panggilan bersiri Ajax


$.ajax({ success: function() { 
  $.ajax({ success: function() {
    $.ajax({ //callbacks... 
        }); 
  }); 
});  
Salin selepas log masuk
Kod dalam kaedah ini kurang boleh dibaca, tidak cekap, tidak jelas dan rumit untuk nyahpepijat dan menyelesaikan masalah.

2). Panggil Ajax secara selari


var promises = []; 
$.ajax({
  success: function() { 
    promises.push('resolved'); 
    check(); 
  } 
}); 
$.ajax({ 
  success: function() { 
    promises.push('resolved'); 
    check();
  } 
}); 
$.ajax({ 
  success: function() { 
    promises.push('resolved'); 
    check(); 
  } 
}); 
var check = function() { //checks for all 3 values in the promises array }
Salin selepas log masuk
Kaedah ini sudah sangat baik untuk panggilan fungsi panggil balik Ia memperoleh data secara selari dan mempunyai kebolehbacaan yang baik. Kelemahannya ialah kod yang panjang, kebolehskalaan yang lemah, dan kerumitan penyahpepijatan dan penyelesaian masalah yang tinggi.

Selepas jQuery 1.5, objek tertunda telah ditambahkan. Oleh itu, keperluan yang sama seperti di atas boleh dicapai dengan cara berikut.

1) Janji


var address = $.ajax({}); 
var tweets = $.ajax({}); 
var facebook = $.ajax({}); 
render_side_bar = function(address, tweets, facebook){ 
  //render sidebar 
}
render_no_side_bar = function () { }
$.when(address, tweets, facebook).then(render_side_bar, render_no_side_bar)
Salin selepas log masuk
Dapat dilihat bahawa kod tersebut mempunyai kebolehbacaan yang baik, kebolehskalaan yang tinggi dan mengurangkan kerumitan nyahpepijat dan penyelesaian masalah dengan banyak.

Maka persoalannya, apakah sebenarnya janji dan objek tertunda?

2. Penerangan terperinci
2. Apakah objek tertunda?
Objek tertunda ialah objek tertunda Ia adalah penyelesaian fungsi panggil balik yang diperkenalkan dalam versi jQuery 1.5 Ia mewakili operasi tertentu untuk diselesaikan dan menyediakan beberapa kaedah untuk membantu pengguna menggunakannya.

Objek tertunda ialah pelaksanaan antara muka Promises. Objek jqXHR yang dikembalikan oleh semua versi Ajax jQuery 1.5 dan yang lebih baru ialah objek tertunda.

2. Beberapa faedah objek tertunda

2.1. Tentukan berbilang fungsi panggil balik untuk operasi yang sama
Salah satu faedah objek tertunda ialah ia membenarkan anda menambah berbilang fungsi panggil balik pada operasi, yang tidak boleh dilakukan dalam Ajax tradisional.

$.ajax("test.html")
  .done(function(){ alert("first success callback!");} )
  .fail(function(){ alert("there is an error!"); } )
  .done(function(){ alert("second success callback!");} );
Salin selepas log masuk
2.2. Tentukan fungsi panggil balik yang sama untuk berbilang operasi

Faedah kedua objek tertunda ialah ia membolehkan anda menentukan fungsi panggil balik yang sama untuk berbilang operasi, yang juga mustahil untuk dicapai dalam ajax tradisional.

$.when($.ajax({}), $.ajax({}))
  .done(function(){ alert("success!"); })
  .fail(function(){ alert("error!"); });
Salin selepas log masuk
2.3. Fungsi panggil balik untuk operasi bukan Ajax

Manfaat ketiga objek tertunda ialah ia tidak lagi terhad kepada operasi ajax Sebarang operasi (operasi ajax atau operasi tempatan/operasi tak segerak atau operasi segerak) boleh menggunakan objek tertunda dan menentukan fungsi panggil balik.

Operasi yang memakan masa yang sangat tipikal


var dfd = $.Deferred(); // create a deferred object
  var wait = function(dtd){
    var tasks = function(){
      alert("over!");
      dtd.resolve(); // change the state of the deferred object from pending to resolved
    };
    setTimeout(tasks,50000);
    return dtd;
  };
Salin selepas log masuk
$.when(wait(dtd))
  .done(function(){ alert("success!"); })
  .fail(function(){ alert("error!"); });
Salin selepas log masuk
2.4. Panggilan berantai

Operasi ajax tradisional dalam jQuery adalah seperti ini:

$.ajax({
  url: "",
   success: function(){
    alert("success!");
   },
   error:function(){
    alert("error!");
   }
});
Salin selepas log masuk
Kejayaan menentukan fungsi panggil balik selepas operasi ajax berjaya, dan ralat menentukan fungsi panggil balik selepas operasi ajax gagal. Sebelum jQuery 1.5, operasi Ajax mengembalikan objek XMLHTTPRequest dan tidak menyokong operasi rantaian. Bermula dari versi 1.5, operasi ajax mengembalikan objek jqXHR, yang merupakan objek tertunda Manfaat penting objek tertunda ialah ia boleh melakukan operasi rantai, kerana semua kaedah objek tertunda mengembalikan objek tertunda.

Operasi ajax semasa ditulis sebagai:

$.ajax({})
  .done(function(){ alert("success!"); })
  .fail(function(){ alert("fail!"); });
Salin selepas log masuk
Membandingkan dua kaedah penulisan, dapat dilihat dengan jelas bahawa done() adalah bersamaan dengan kaedah kejayaan operasi ajax tradisional, dan fail() adalah bersamaan dengan kaedah fail operasi ajax tradisional. Berbanding dengan kaedah penulisan tradisional, kebolehbacaan kod dipertingkatkan.

3.Kaedah objek tertunda

3.1 Penggunaan asas
(1).Jana objek tertunda

var dfd = $.Deferred(); //buat objek tertunda
(2).Keadaan objek tertunda

Objek tertunda mempunyai tiga keadaan

belum selesai: menunjukkan bahawa operasi berada dalam keadaan belum selesai dan sebarang objek tertunda (tertunda) bermula dalam keadaan belum selesai.
diselesaikan: menunjukkan operasi berjaya.
ditolak: menunjukkan bahawa operasi gagal. Kaedah state() mengembalikan keadaan semasa objek tertunda.

$.Deferred().state(); // 'pending'
$.Deferred().resolve().state(); // 'resolved'
$.Deferred().reject().state(); // 'rejected'
Salin selepas log masuk
(3).Tukar keadaan objek tertunda

Panggil deferred.resolve() atau deferred.resolveWith() untuk menukar Deferred kepada keadaan diselesaikan dan segera laksanakan doneCallbacks dalam tetapan.

var callbackFunc = function(){console.log(arguments[0]);}
var dfd = $.Deferred();
dfd.done(callbackFunc);
dfd.resolve("hello"); //'hello'
Salin selepas log masuk
Panggil deferred.reject() atau deferred.rejectWith() untuk menukar Deferred kepada status ditolak dan segera laksanakan failCallbacks dalam tetapan.

var callbackFunc = function(){console.log(arguments[0]);}
var dfd = $.Deferred();
dfd.fail(callbackFunc);
dfd.reject("fail"); //'fail'
Salin selepas log masuk
(4).Ikat fungsi panggil balik

Apabila keadaan objek tertunda berubah, fungsi panggil balik akan dicetuskan. Sebarang panggilan balik yang ditambahkan pada objek ini menggunakan deferred.then(), deferred.always(), deferred.done() atau deferred.fail() akan dibariskan untuk pelaksanaan.

belum selesai-->diselesaikan, laksanakan sebarang doneCallbacks (dinyatakan oleh done()) dalam tetapan dan parameter dihantar kepada doneCallbacks dengan diselesaikan.

belum selesai-->ditolak, laksanakan sebarang failCallbacks (dinyatakan oleh fail()) dalam tetapan, dan parameter dihantar ke failCallbacks dengan diselesaikan.
belum selesai-->diselesaikan/ditolak, melaksanakan panggilan balik yang ditentukan oleh always(), dan parameter dihantar kepada panggilan balik daripada diselesaikan.

var f1 = function(){console.log("done");}, 
   f2 = function(){console.log("fail");}, 
   f3 = function(){console.log("always");};

var dfd = $.Deferred();
dfd.done(f1).fail(f2).always(f3);

//if
dfd.resolve(); //'done' 'always'
//if
dfd.reject(); //'fail' 'always'

Salin selepas log masuk

如果在状态更改后附件一个callback则会立即执行callback,因此不必担心deferred对象何时被resolved或者rejected,因为无论何时,参数都会正确地传递给callbacks。

var fun1 = function(){console.log(arguments[0]);},
  fun1 = function(){console.log(arguments[0]);};
var dfd = $.Deferred();
dfd.done(fun1);
dfd.resolve("hello"); //'hello'
dfd.done(fun2); //'hello'
Salin selepas log masuk

3.2.deferred对象的方法
(1)$.Deferred([beforeStart]) -- 创建一个deferred对象,参数类型为Function,是一个在构造函数之前调用的函数。

var func = function(){console.log("start");} 
var dfd = $.Deferred(func); //'start' create a deferred object
Salin selepas log masuk

(2)deferred.done(doneCallbacks [,doneCallbacks]) -- 当deferred(延迟)对象解决时,调用添加处理程序。

args:接受一个或者多个参数,所有的参数都可以是一个单一的函数或者函数数组,当deferred(延迟)对象解决时,doneCallbacks被调用。回调是依照他们添加的顺序执行的。

var func1 = function(){console.log("1");},
   func2 = function(){console.log("2");},
   func3 = function(){console.log("3");};
var dfd = $.Deferred();
dfd.done([func1,func2],func3,[func2,func1]);
dfd.resolve(); // "1 2 3 2 1"
Salin selepas log masuk

(3)deferred.fail(failCallbacks [,failCallbacks]) -- 当deferred(延迟)对象拒绝时,调用添加处理程序。

args:接受一个或者多个参数,所有的参数都可以是一个单一的函数或者函数数组,当deferred(延迟)对象拒绝时,failCallbacks被调用。回调是依照他们添加的顺序执行的。

var func1 = function(){console.log("1");},
   func2 = function(){console.log("2");},
   func3 = function(){console.log("3");};
var dfd = $.Deferred();
dfd.fail([func1,func2],func3,[func2,func1]);
dfd.reject(); // "1 2 3 2 1"
Salin selepas log masuk

(4)deferred.resolve(args) and deferred.resolveWith(context [,args]) -- 解决Deferred(延迟)对象,并根据给定的args参数(resolveWith给定context)调用任何doneCallbacks。

参数:args -- type(object),传递给回调函数(doneCallbacks)的可选的参数,

context -- type(object),Context(上下文)作为this对象传递给完成回调函数(doneCallbacks)。

var func = function(arg){console.log(arg);};
$.Deferred().done(func).resolve("done!"); //'done!'
var func = function(arg1,arg2){console.log(arg1.name + ',' + arg2);};
$.Deferred().done(func).resolve({name:'Lucy'},'How are you!'); // 'Lucy,How are you!'
Salin selepas log masuk

resolve和resolveWith的区别就等同于fire和fireWith的区别。

var func = function () {
  console.log(this.name + ',' + arguments[0] + ' ' + arguments[1] + ' ' + arguments[2]);
};
$.Deferred().done(func).resolveWith({ name: "Lucy" }, ["How", "are", "you!"]);//'Lucy,How are you!'
Salin selepas log masuk

(5)deferred.reject(args) and deferred.rejectWith(context [,args]) -- 拒绝Deferred(延迟)对象,并根据给定的args参数(rejectWith给定context)调用任何failCallbacks。

参数:args -- type(object),传递给回调函数(doneCallbacks)的可选的参数,

context -- type(object),Context(上下文)作为this对象传递给完成回调函数(doneCallbacks)。

var func = function(arg){console.log(arg);};
$.Deferred().fail(func).reject("error!"); //'error!'
var func = function(ctx,arg){console.log(ctx.name + ',' + arg);};
$.Deferred().fail(func).reject({name:'Mark'},'What happend!'); // 'Mark,What happend!'
Salin selepas log masuk

reject和rejectWith的区别就等同于fire和fireWith的区别。

var func = function () {
  console.log(this.name + ',' + arguments[0] + ' ' + arguments[1]);
};
$.Deferred().fail(func).rejectWith({ name: "Mark" }, ["what", "happend!"]); // 'Mark,What happend!'
Salin selepas log masuk

(6)deferred.promise([target]) -- 返回Deferred(延迟)的Promise(承诺)对象。

参数可选,无参数时返回一个Promise(承诺)对象,Promise(承诺)对象仅会暴露那些需要绑定额外的处理或判断状态的延迟方法(then, done, fail, always,pipe, progress, state,和 promise)时,并不会暴露任何用于改变状态的延迟方法(resolve, reject, notify,resolveWith, rejectWith, 和 notifyWith)。使用Promise(承诺)会阻止其他人破坏你制造的promise。

function asyncEvent() {
   var dfd = jQuery.Deferred();

    // Resolve after a random interval
    setTimeout(function () {
       dfd.resolve("hurray");
    }, Math.floor(400 + Math.random() * 2000));

    // Reject after a random interval
    setTimeout(function () {
       dfd.reject("sorry");
    }, Math.floor(400 + Math.random() * 2000));

    // Show a "working..." message every half-second
    setTimeout(function working() {
       if (dfd.state() === "pending") {
          dfd.notify("working... ");
           setTimeout(working, 500);
        }
     }, 1);

      // Return the Promise so caller can't change the Deferred
      return dfd.promise();
 }

// Attach a done, fail, and progress handler for the asyncEvent
$.when(asyncEvent()).then(
    function (status) {
       alert(status + ", things are going well");
    },
    function (status) {
       alert(status + ", you fail this time");
    },
    function (status) {
       alert(status);
    }
);

Salin selepas log masuk

有参数时,会将事件绑定到参数上,然后返回该参数对象(返回的实际是一个扩展的Promise(承诺)对象)。

var obj = {
  hello: function (name) {
    alert("Hello " + name);
  }
},
// Create a Deferred
dfd = $.Deferred();

// Set object as a promise
dfd.promise(obj);

// Resolve the deferred
dfd.resolve("John");

// Use the object as a Promise
obj.done(function (name) {
   obj.hello(name); // will alert "Hello John"
}).hello("Karl");

Salin selepas log masuk

(7)$.when(deferreds) -- 提供一种方法来执行一个或多个对象的回调函数。

参数:type(Deferred),一个或多个延迟对象,或者普通的JavaScript对象。

参数仅传入一个单独的Deferred对象,返回它的Promise对象。

function func() {
  var dfd = $.Deferred();
  setTimeout(function () {
    dfd.resolve("hurry");
  }, 500);
  return dfd.promise();
};

$.when(func()).done(function (arg) {
  alert(arg); /*alert "hurry"*/
});

Salin selepas log masuk

参数传入一个非Deferred和Promise对象,那么该参数会被当成一个被解决(resolved)的延迟对象,并且绑定到上面的任何doneCallbacks都会被立即执行。

$.when( { name: 123 } ).done(
  function(arg) { alert(arg.name); } /* alerts "123" */
);
Salin selepas log masuk

无参数,返回一个resolved(解决)状态的Promise对象。

$.when().state(); // "resolved"
Salin selepas log masuk

参数为多个Deferred对象,该方法根据一个新的“宿主” Deferred(延迟)对象,跟踪所有已通过Deferreds聚集状态,返回一个Promise对象。当所有的延迟对象被解决(resolve)时,“宿主” Deferred(延迟)对象才会解决(resolved)该方法,或者当其中有一个延迟对象被拒绝(rejected)时,“宿主” Deferred(延迟)对象就会reject(拒绝)该方法。

var d1 = $.Deferred();
var d2 = $.Deferred();
 
$.when( d1, d2 ).done(function ( v1, v2 ) {
  console.log( v1 ); // "Fish"
  console.log( v2 ); // "Pizza"
});
 
d1.resolve( "Fish" );
d2.resolve( "Pizza" );
Salin selepas log masuk

(8)deferred.then(doneFilter [,failFilter] [,progressFilter]) -- 当Deferred(延迟)对象解决,拒绝或仍在进行中时,调用添加处理程序。

参数:

doneFilter -- type(Function),当Deferred(延迟)对象得到解决时被调用的一个函数。
failFilter -- type(Function),当Deferred(延迟)对象拒绝时被调用的一个函数,可选。
progressFilter -- type(Function),当Deferred(延迟)对象生成进度通知时被调用的一个函数,可选。
其实,then方法可以理解成,把done(),fail(),progress()合在一起写。

var filterResolve = function () {
   var dfd = $.Deferred(),
     filtered = dfd.then(function (value) { return value * 2; });
   dfd.resolve(5);
   filtered.done(function (value) { console.log(value); });
};
filterResolve(); //'10'

var defer = $.Deferred(),
   filtered = defer.then(null, function (value) {
     return value * 3;
   });

defer.reject(6);
filtered.fail(function (value) {
   alert("Value is 3*6 = " + value);
});

Salin selepas log masuk

(9)deferred.always(alwaysCallbacks [,alwaysCallbacks]) -- 当Deferred(延迟)对象解决或拒绝时,执行alwaysCallbacks。

顾名思义,只要Deferred对象的状态发生更改(解决或者拒绝)均会调用alwaysCallbacks。

(10)deferred.state() -- 获取一个Deferred(延迟)对象的当前状态,不接受任何参数。

$.Deferred().state();//"pending"
上面讲述过deferre(延迟)对象的三种状态,这个方法对于debug非常有用,例如,在准备reject一个deferred对象之前,判断它是否处于resolved状态。

(11)deferred.notify(args) and deferred.notifyWith()

(12)deferred.progress()

(13)deferred.pipe()

(14).promise()

(15)deferred.isRejected() 和 deferred.isResolved() -- 从jQuery 1.7开始被弃用,较新版本的jQuery类库中已经被删除,可以使用state()方法代替这两个方法。

(16)deferred.pipe() -- 从jQuery 1.8开始被弃用。

4.什么情况下使用deferred对象和Promises?
上面讲了很多,那么我们究竟在什么情况下使用Deferred对象和Promises对象呢?

(1)复杂的动画

不知道动画什么时候结束,但是又必须在动画结束的时候做一些操作或者是启动其他的动画,这种情况下,如果采用其他的方式,很容易导致代码可读性差,尤其是还夹带着一些其它的操作,比如渲染、表单操作等,现在jQuery会为你的动画操作返回一个Promise,这样这些动画可以进行链式操作。

(2)处理队列

复制代码 代码如下:
window.queue = $.when() $('#list').on('click', function() { window.queue = window.queue.then(function() { //do the thing }) } )

(3)The Wait promise

function wait(ms) { 
  var deferred = $.Deferred(); 
  setTimeout(function(){deferred.resolve()}, ms);
  return deferred.promise(); 
}

wait(1500).then(function () {
    // After 1500ms this will be executed 
});
Salin selepas log masuk

(4)典型的Ajax操作

$.when($.ajax({}), $.ajax({}))
  .done(function(){ alert("success!"); })
  .fail(function(){ alert("error!"); });
Salin selepas log masuk

(5)一些耗时的大循环操作

以上就是本文的全部内容,希望对大家的学习有所帮助。

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan