jQuery.deferred()方法
阿新 • • 發佈:2018-12-08
如果不懂 $.when() 方法的請看我的上一篇部落格
/** * 定義一個很耗時的 wait 函式 * 這個地方不呼叫 resolve 就可以執行, 是因為 wait 並不是一個 promise 或者 deferred * done()方法會立即執行,起不到回撥函式的作用 * $.when()的引數只能是deferred物件,所以必須對wait()進行改寫 */ var wait = function() { var tasks = function() { console.log('執行完畢'); } setTimeout(tasks, 2000) } $.when(wait()) .done(function() { console.log("哈哈,成功了!"); }) .fail(function() { console.log("出錯啦!"); }); /** * 改寫 wait() * 再 wait 函式執行完之後, 函式內部呼叫了成功的方法就會自動執行 done 函式 * 當然你也可以 呼叫失敗的方法, 只需要把 `dtd.resolve()` 改成 `dtd.reject()` 即可 * Deferred 是有三個狀態的 * 第一個狀態 : 待開始的狀態 * 第二個狀態 : 成功時的狀態 * 第三個狀態 : 失敗時的狀態 */ // 第一種寫法(沒有封裝) var dtd = $.Deferred() // 建立一個 Deferred 物件 var wait = function(dtd) { // 要求傳入一個 deferred 物件, 不然這個函式沒有意義了 var tasks = function() { //這裡可以有大量的複雜操作 console.log("執行完畢"); // 執行完畢 dtd.resolve() // 表示非同步任務已經完成, 改變 deferred 物件的狀態 // dtd.reject() // 表示非同步任務失敗, 改變 deferred 物件的狀態 } setTimeout(tasks, 2000) // 等待 2m 後執行 return dtd // 一定要有返回值, 並且 一定是這個 物件 } $.when(wait(dtd)) .done(function() { console.log("哈哈,成功了!"); }) // 哈哈,成功了! .fail(function() { console.log("出錯啦!"); }); // 第二種寫法 (封裝版) function waitHandle() { var dtd = $.Deferred() var wait = function(dtd) { var tasks = function() { console.log('執行完畢') // 執行完畢 dtd.resolve() // dtd.reject() } setTimeout(tasks, 2000) return dtd } return wait(dtd) } var w = waitHandle() // 此處同樣可是使用 then 方法來呼叫 w.then(function() { console.log('ok 1'); // ok 1 }, function() { console.log('err 1'); }).then(function() { console.log('ok 1'); // ok 1 }, function() { console.log('err 1'); }) /** * 這樣呢 : 有一個弊端就是, 可以手動修改狀態. * 舉梨 : 比如 我們函式中, 定義的是 dtd.resolve() 方法,但是我們再程式的最後一行加上 w.reject() * 結果 就很有意思了, 會再程式以執行的時候, 改變 dtd 的狀態, 然後立即執行 `done()`, 等到 延時器 結束的時候再執行 `console.log('執行完畢')` * 這樣就不是我們想要的了 * 所以 : 就引出了 deferred.promise() 方法. */ // + w.resolve()