1. 程式人生 > >jQuery回撥、遞延物件總結(下篇) —— 解密jQuery.when方法

jQuery回撥、遞延物件總結(下篇) —— 解密jQuery.when方法

前言:

前一篇文章中重點總結了一下then方法,它主要用來處理多個非同步任務按順序執行,即前一個任務處理完了,再繼續下一個,以此類推;

而這一章節jQuery.when方法也是處理多個非同步任務,它把多個非同步任務(Promise物件)合併為一個Promise物件,這個合併後的Promise物件

到底是如何來更新它的狀態,即何時執行,拒絕?讓我們繼續往下看吧!

jQuery回撥、遞延物件總結篇索引:

設計思路(意圖)

執行jQuery.when將會返回一個Promise物件,我們稱作由when生成的Promise物件,如果給定的所有Promise物件均已執行,就立即執行

由when方法產生的Promise物件,如果給定的Promise物件中有任意一個被拒絕,就立即拒絕由when生成的Promise物件,這樣做的意圖

好像就是為了解決這樣一種需求:在指定的多個非同步事件都完成了,然後才能幹自己想幹的事情

原始碼解析

jQuery.extend({
    // Deferred helper
    // 引數為Promise物件,我們稱作:給定的Promise物件
    // when函式內部的deferred物件,我們稱作:由when生成的Promise物件
    when: function( subordinate /* , ..., subordinateN 
*/ ) { var i = 0, resolveValues = core_slice.call( arguments ), length = resolveValues.length, // the count of uncompleted subordinates // 用來儲存給定的未執行(解決)的Promise物件的個數 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
// the master Deferred. If resolveValues consist of only a single Deferred, just use that. // 我們稱deferred為when生成的Promise物件 deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values updateFunc = function( i, contexts, values ) { return function( value ) { contexts[ i ] = this; values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; // 如果給定的任意一個Promise物件未執行或拒絕,則通知由when生成的Promise物件為pending狀態 // 注:contexts是由所有給定的Promise物件組成的陣列, // values是由處理所有給定的Promise物件的回撥的引數組成的陣列 if( values === progressValues ) { deferred.notifyWith( contexts, values ); } // 如果給定的Promise物件已執行(解決),且當未執行的Promise物件個數為0, // 即:給定的所有Promise物件都已執行(解決),則立即執行由when生成的Promise物件 // 注:contexts是由所有給定的Promise物件組成的陣列, // values是由處理所有給定的Promise物件的回撥的引數組成的陣列(請看例項1) else if ( !( --remaining ) ) { deferred.resolveWith( contexts, values ); } }; }, progressValues, progressContexts, resolveContexts; // add listeners to Deferred subordinates; treat others as resolved if ( length > 1 ) { progressValues = new Array( length ); progressContexts = new Array( length ); // resolveValues = core_slice.call( arguments ) // 別忘了最上面的這行程式碼 resolveContexts = new Array( length ); for ( ; i < length; i++ ) { // 如果給定when的引數是一個Promise物件,則通知由when生成的Promise物件,通知什麼,如何通知? // 如果給定的Promise物件已執行,則執行由when生成的Promise物件(要等到所有給定Promise物件全部執行) // 如果給定的任意一個Promise物件已拒絕,則拒絕由when生成的Promise物件 // 如果未執行或拒絕,預設是pending狀態 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { resolveValues[ i ].promise() .done( updateFunc( i, resolveContexts, resolveValues ) ) .fail( deferred.reject ) .progress( updateFunc( i, progressContexts, progressValues ) ); } // 如果給定的不是一個Promise物件,那麼負責減一 else { --remaining; } } } // if we're not waiting on anything, resolve the master // 如果傳遞給when的引數都不是遞延物件,則執行由when生成的Promise物件 if ( !remaining ) { // resolveContexts為一個空陣列new Array( length ),resolveValues是由when引數組成的一個數組 deferred.resolveWith( resolveContexts, resolveValues ); } return deferred.promise(); } });

例項:關於執行由when生成的Promise物件的引數的問題

var promiseA = $.Deferred();
var promiseB = $.Deferred();

var doneFn = function(arg){
    console.log(arg);
};

promiseA.done(doneFn);
promiseB.done(doneFn);

promiseA.resolve('A'); // 'A'
promiseB.resolve('B'); // 'B'

var whenFn = function(arg1, arg2){
    console.log(this[0] === promiseA.promise()); // true
    console.log(this[1] === promiseB.promise()); // true
    console.log('promise' + arg1 + ', promise' + arg2 + ' All done!');
};
var whenPromise = jQuery.when(promiseA, promiseB);
whenPromise.done(whenFn); // true true 'promiseA, promiseB All done!'

jQuery回撥、遞延物件總結:

遞延物件中的then方法作用於使多個非同步任務按照順序執行,而jQuery.when方法作用於在多個併發的非同步任務執行完畢後再幹自己感興趣的事情;

jQuery遞延物件是基於jQuery回撥物件架構的,如果你想熟練掌握jQuery遞延物件,請先移步jQuery.Callbacks物件

PS: 如有描述錯誤,請幫忙指正,如果你們有不明白的地方也可以發郵件給我,

  如需轉載,請附上本文地址及出處:部落格園華子yjh,謝謝!

相關推薦

jQuery物件總結下篇) —— 解密jQuery.when方法

前言: 前一篇文章中重點總結了一下then方法,它主要用來處理多個非同步任務按順序執行,即前一個任務處理完了,再繼續下一個,以此類推; 而這一章節jQuery.when方法也是處理多個非同步任務,它把多個非同步任務(Promise物件)合併為一個Promise物件,這個合併後的Promise物件 到底是

jQuery物件總結中篇) —— 神奇的then方法

前言: 什麼叫做遞延物件,生成一個遞延物件只需呼叫jQuery.Deferred函式,deferred這個單詞譯為延期,推遲,即延遲的意思,那麼在jQuery中 又是如何表達延遲的呢,從遞延物件中的then方法或許能找到這種延遲的行為,本文重點解讀遞延物件中的then方法 jQuery回撥、遞延物件

jQuery物件總結上篇)—— jQuery.Callbacks

前言: 作為引數傳遞給另一個函式執行的函式我們稱為回撥函式,那麼該回調又是否是非同步的呢,何謂非同步,如:作為事件處理器,或作為引數傳遞給 (setTimeout,setInterval)這樣的非同步函式,或作為ajax傳送請求,應用於請求各種狀態的處理,我們可以稱為非同步回撥,jQuery.Callba

js進階四(jspromisepromise巢狀異常處理jquery使用promise)

同步讀取 我們來看一個從檔案讀取內容的例子,以下是這個例子的目錄結構 我們看下promiser.js的程式碼如下: const fs = require("fs") const path = require("path") function getFile

PHP之匿名函式與閉包

回撥函式:通俗的解釋就是把函式作為引數傳入進另一個函式中使用;PHP中有許“需求引數為函式”的函式,像array_map,usort,call_user_func_array之類,他們執行傳入的函式,然後直接將結果返回主函式。好處是函式作為值使用起來方便,而且程式碼簡潔,可讀

前端面試——PromiseGenerator和async-await

首先我們回顧一下javascript非同步的發展歷程。 ES6 以前:   回撥函式(callback):nodejs express 中常用,ajax中常用。 ES6:   promise物件:nodejs最早有bluebird promise的雛形,axios中常

非同步事件驅動協程概念辨析

同步和非同步: 面試問題什麼是非同步非阻塞 A. 同步 所謂同步,就是在發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回。 B. 非同步 非同步的概念和同步相對。 當一個非同步過程呼叫發出後,先返回,呼叫者不會立刻得到結果。 實際處理這個呼叫的部件是在呼叫發出後, 通過狀態、通知來通知

Android Activity的onStop()與onDestroy() 緩慢,時呼叫的問題解決方案

前段時間做專案時遇到奇葩問題,特此記錄: 問題發現: 我們的專案在語句翻譯功能裡用到了百度語音識別和語音合成,把相關程式碼封裝到了library裡面,把library庫放到專案A裡面執行正常,同樣的庫移植到專案B裡面,居然有問題!!! 具體問題就是第一次進入Activity時正常,但是當退出

Java中的單例模式工廠模式介面異常

for迴圈:起點為基本資料型別,包括boolean . equals():重寫原因,希望在地址不同但內容相同時也能返回true。 匿名物件:直接new出物件,不需要物件名來接收。 new Person().show(); 內部類:類

Java程式設計之委託代理內部類以及匿名內部類(閉包)

最近一直在看Java的相關東西,因為我們在iOS開發是,無論是Objective-C還是Swift中,經常會用到委託代理回撥,以及Block回撥或者說是閉包回撥。接下來我們就來看看Java語言中是如何實現委託代理回撥以及閉包回撥的。當然這兩個技術點雖然實現起來並不困難,但是,這回調在封裝一些公用元件時還是特別

java 三種呼叫機制同步非同步)

java中存在三種呼叫機制 1:同步呼叫:一種阻塞式呼叫,呼叫方要等待對方執行完畢才返回,它是一種單向呼叫 2:回撥:一種雙向呼叫模式,也就是說,被呼叫方在介面被呼叫時也會呼叫對方的介面; 3:非同步呼叫:一種類似訊息或事件的機制,不過它的呼叫方向剛好相反

JavaScript踩坑筆記10---同步非同步

JavaScript踩坑筆記10---同步回撥、非同步回撥 同步回撥: 非同步回撥: 同步回撥: 同步回撥指的是,回撥函式和主函式的執行是同步的,回撥函式在主函式內執行,並且主函式要等回撥函式執行完畢以後,才能執行。 舉例說明。 // 定

Android中介面方法

在android開發中我們很多地方都用到了方法的回撥,回撥就是把方法的定義和功能匯入實現分開的一種機制,目的是為了解耦他的本質是基於觀察者設計模式,即觀察者設計模式的的簡化版,例如:在下載時候的進度回撥,在adapter與activity之間的回撥,在javabean和fr

20.php匿名函式和閉包操作

    現在的php是即支援面向物件的語言由支援面向過程的語言,在開發過程中我們往往會混合使用,回撥會讓我們容易將兩種編碼方式做整合,做到優秀的插拔。而閉包操作和回撥都是建立在匿名函式基礎之上的。 &

iOS整合微信支付的一些坑:onResp不只顯示一個確定按鈕

iOS整合微信支付總體來說還是比較容易的(如果沒有那些坑的話),所有文件都在:    https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1甚至只要看:    https://pay.weixin.qq.com/w

關於訊息事件【轉】

二,回撥函式、訊息和事件例程                        呼叫(calling)機制從彙編時代起已經大量使用:準備一段現成的程式碼,呼叫者可以隨時跳轉至此段程式碼的起始地址,執行完後再返回跳轉時的後續地址。CPU為此準備了現成的呼叫指令,呼叫時可以壓棧保護現場,呼叫結束後從堆疊中彈出現場地址

面向物件總結php)

文章來自:原始碼線上https://www.shengli.me/php/59.html;    一、面向物件有一下幾個特性:   重用性 ——每個物件模組都可以在專案中重複使用。 拓展性——模組上新增新功能是很方便的. 靈活

JQuery 總結4) jQuery 篩選查詢 等

1. hasClass(“class”) 判斷是否有這個class2. addClass(“class”)增加, removeClass(“class”)刪除,toggleClass(“cc”)有就刪cc,沒有增加cc。 $("li").click(function () { $(this).togg

JQuery 總結4) jQuery 篩選查找 等

cti span ttr ddc pan this attr font dcl 1. hasClass(“class”) 判斷是否有這個class2. addClass(“class”)增加, removeClass(“class”)刪除,toggleClass(“cc”)

javascript--函式基礎函式的定義/作用域,函式,即時函式,內部私有)函式,返回函式的函式,重寫自己的函式)

函式源於數學對映運算,它定義了一種關係,這種關係使一個集合裡的每一個元素對應到另一個(可能相同的)集合裡的唯一元素 javascript中: 函式是程式碼塊,一段被封閉嚴實的程式碼塊 函式是資料:使用者可以把函式作為 值 賦值給 變數 函式是一種物件,它是一類抽象類(建構函式),所有