1. 程式人生 > >jQuery的鏈式呼叫原理,Promise的鏈式呼叫,this的問題

jQuery的鏈式呼叫原理,Promise的鏈式呼叫,this的問題

最近被問到這個問題,jq的鏈式呼叫原理,當時比較懵=。=,畢竟現在jq接觸的機會變很少了。

jq的鏈式呼叫

jq的鏈式呼叫其實就是比如我們在選擇dom的時候,

$('input[type="button"]')
    .eq(0).click(function() {
        alert('點選我!');
}).end().eq(1)
.click(function() {
    $('input[type="button"]:eq(0)').trigger('click');
}).end().eq(2)
.toggle(function() {
    $('.aa').hide('slow');
}, function() {
    $('.aa').show('slow');
});

比如如上程式碼,先選擇type型別為button的所有DOM,然後再選擇第一個...

我們自然想到每次其實就是返回選擇後的結果,在js裡面有什麼東西可以指代這個嗎?
如果你想到this就對了。

jq的方法都是掛在原型的,那麼如果我們每次在內部方法返回this,也就是返回例項物件,那麼我們就可以繼續呼叫原型上的方法了,這樣的就節省程式碼量,提高程式碼的效率,程式碼看起來更優雅。

但是也會出現一個問題:所有物件的方法返回的都是物件本身,也就是說沒有返回值,所以這種方法不一定在任何環境下都適合。

Promise的鏈式呼叫

promise的鏈式呼叫如:

function start() {  
    return new Promise((resolve, reject) => {  
      resolve('start');  
    });  
  }  
    
  start()  
    .then(data => {  
      // promise start  
      console.log('result of start: ', data);  
      return Promise.resolve(1); // p1  
    })  
    .then(data => {  
      // promise p1  
      console.log('result of p1: ', data);  
      return Promise.reject(2); // p2  
    })  
    .then(data => {  
      // promise p2  
      console.log('result of p2: ', data);  
      return Promise.resolve(3); // p3  
    })  
    .catch(ex => {  
      // promise p3  
      console.log('ex: ', ex);  
      return Promise.resolve(4); // p4  
    })  
    .then(data => {  
      // promise p4  
      console.log('result of p4: ', data);  
    });  

Promise的then其實都是實現了 thenable 介面,每個 then 都返回一個新的promise,除了第一個是start的例項其他的已經不是一個promise了。

reject的下面的then都會跳過(

更新

這裡其實說錯了,應該是then 裡面的回撥被忽略執行,如果在這個then直接寫一個console.log()你發現還是會列印,感謝jjc大佬特別指出這一點的錯誤,當 Promise 的狀態為 rejected 時,這個回撥函式沒有被執行,並不是 then 函式沒有被執行。

eg:

Promise.reject(1).then(console.log('foo bar'));

依然輸出了 foo bar,可見 then 函式其實已經執行了。
如果寫成:

Promise.reject(1).then(() => console.log('foo bar'));

就不會輸出了。只是說,then 函式中傳入了一個回撥函式,當 Promise 的狀態為 rejected 時,這個回撥函式沒有被執行,並不是 then 函式沒有被執行。

做個合適的類比。以下 jQuery 鏈式呼叫:

$('#a_id_selector')
  .addClass('someclassname')
  .click(() => console.log('foo bar'))
  .prop('type', 'text');

執行這段程式碼,也沒有輸出 foo bar,但是我們不能說 click 函式被忽略掉了。只是裡面傳入的回撥函式的條件沒有成立,這裡是點選的條件,上面就是resolve的條件。

),只有catch才會捕捉到。

promise的鏈式呼叫就和jq完全不一樣了,promise鏈式呼叫的特點:
這裡寫圖片描述

這裡寫圖片描述

關於Promise的實現,我做了一個簡單的promise:

function easyPromise(fn) {
    var that = this;
    this.then = function (cb) {
        that.cb = cb;
      }
    this.resolve = function (data) {
        that.cb(data);
    }

    fn(this.resolve);
}

new easyPromise((resolve)=>{
    setTimeout( ()=> {
        resolve("延遲執行");
    },1000);
}).then( (data) => {
    console.log(data);
} )

可以簡寫成

// 定義一個要傳給 promise 的函式,它接收一個函式(resolve)作為引數。
// resolve 的作用是在合適的時間,通知 promise 應該要執行 then 裡面的回撥函數了。
function promiseCallback (resolve) {
    setTimeout(() => {
       resolve("延時執行")
    }, 1000)
 }
 
 // 定義一個 要傳給 then 的回撥函式
 function thenCallback (data) {
     console.log(data)
 }
 
 // 例項化 promis,並分別傳入對應的回撥
 new easyPromise(promiseCallback)
 .then(thenCallback)

1.先通過 then 把 thenCallback 存起來
2.執行 promise 括號裡的函式,並把事先定義好的 resolve 函式作為引數傳給他

fn(this.resolve)

3.執行 promiseCallback 我們的邏輯就跳到 promiseCallback 函式內部去

setTimeout(() => {
  resolve("延時執行")
}, 1000)

邏輯很簡單,就是等待1秒後,執行 resolve 函式, 這個 resolve 哪來的呢?
fn(this.resolve) -> promiseCallback (resolve) -> resolve

4.執行 resolve 我們的邏輯就跳到 resolve 函式內部去

that.cb(data)

這個 that.cb 又是哪來的呢? 就是我們第一步儲存的 then括號裡面的回撥函式,也就是 thenCallback

console.log(data)

所以就在1秒後輸出 延時執行

關於this

this是js函式執行過程中的一個物件,環境物件。

誒,自己總結的發現還是沒阮老師的好。。所以還是看阮老師的吧,連結

相關推薦

ES6學習路上的小學生promise處理非同步操作簡易原始起步之用。先能用再深究!

ES6的promise物件,讓我們更容易的處理這樣的需求:執行完一個方法以後,再去執行下一個方法。 理解尚淺之時,先用於專案之中。 1 var promise1 = new Promise(function(resolve, reject) { 2 //

jQuery呼叫原理Promise呼叫this的問題

最近被問到這個問題,jq的鏈式呼叫原理,當時比較懵=。=,畢竟現在jq接觸的機會變很少了。 jq的鏈式呼叫 jq的鏈式呼叫其實就是比如我們在選擇dom的時候, $('input[type="button"]') .eq(0).click(function() { alert('點選我!

從零開始學 Web 之 jQuery(七)事件冒泡事件引數物件程式設計原理

一、事件冒泡與阻止事件冒泡 事件冒泡:當一個元素觸發某個事件的時候,會把這個事件傳播到其父元素,一直到頂層元素。 阻止事件冒泡:在被觸發事件的子元素中新增 return false; 即可。 二、事件的觸發 之前講的繫結事件是事件觸發後的事件處理過程,並且上面的事件觸發是被動的事件觸發,怎麼可以主動觸發事

js省略物件名寫完一個屬性直接寫另一個 . 屬性名這種語法糖叫 呼叫

正常寫法的程式碼(chart.lbl重複多次): chart.lbl = chart.renderer.label('You selected ' + selectedPoints.length + ' points', 100, 60); chart.lbl.attr({ paddin

呼叫原理

  var testFn = function () {} testFn.prototype = { fn1: function () { console.log(this); console.log('fn1'); return this; }, fn2

數據結構之線性表代碼實現順序存儲存儲靜態表(選自大話數據結構)

新元素 error 失敗 尾插法 後繼 順序存儲 %d 帶表頭 tle 一,線性表順序存儲 #include <stdio.h> #include <string.h> #include <ctype.h> #i

jQuery式調用原理

query proto 使用 內部 nbsp clas span () .proto (1).鏈式調用 1 $("#mybtn").css("width","100px") 2 3 .css("height","100px

Promise回調的使用

ESS reject gin 方法 失敗 ID UC 第一個 成功 /*Promise通常配合then方法來鏈式的使用,then方法裏面第一個回調函數表示成功狀態,也就是resolve,第二個是失敗狀態-reject,如果默認寫一個參數的話,默認resolve*/

JavaScript繼承基礎講解原型、借用構造函數、混合模式、原型式繼承、寄生繼承、寄生組合式繼承

push 需要 覆蓋 pan 只需要 童鞋 java var 自定義 說好的講解JavaScript繼承,可是遲遲到現在講解。廢話不多說,直接進入正題。   既然你想了解繼承,證明你對JavaScript面向對象已經有一定的了解,如還有什麽不理解的可以參考《面向對象JS基礎

過濾器、過濾器呼叫原理與順序、過濾器配置細節、過濾器過濾型別

過濾器鏈呼叫原理與順序: web伺服器根據Filter在web.xml檔案中的註冊順序,決定先呼叫哪個Filter,當第一個Filter的doFilter方法被呼叫時,web伺服器會建立一個代表Filter鏈的FilterChain物件傳遞給該方法。在doFilter

深入淺出JS原型的工作原理

前言:原型鏈,即原型鏈條。它是由原型、原型的原型、原型的原型的原型...這一規則組合成的,經常被應用於繼承。 原型的作用在JS中,每個物件都有自己的原型。當我們訪問物件的屬性和方法時,JS會先訪問物件本身的屬性和方法。如果物件本身不包含這些屬性和方法,則訪問物件對應的原型。

無法執行該操作因為接服務器 "XXX" 的 OLE DB 訪問接口 "SQLNCLI10" 無法啟動分布事務。

設置 ted -c inf 服務器管理 網絡 右擊 window 存儲過程 在存儲過程中使用事務,並且使用鏈接服務器時,報以下錯誤: 無法執行該操作,因為鏈接服務器 "XXX" 的 OLE DB 訪問接口 "SQLNCLI10" 無法啟動分布式事務。 鏈接服務器"XXX

區塊系統開發實現原理區塊為什麼叫區塊

區塊鏈交易平臺系統開發原理:“區塊鏈使用強大的加密技術來維護虛擬安全,通過整體計算機的複雜數學運算機制來驗證,刪除與儲存,區塊與之前的區塊相互關聯,因此形成區塊鏈。” 區塊鏈分為三大類:公有鏈,私有鏈,聯盟鏈 公有鏈:世界上任何個體或者團體都可以傳送交易,且

MapReduce 順序組合 迭代組合式

1、順序組合式 順序組合式就是按照指定順序執行任務如:mapreduce1 --> mapreduce2 --> mapreduce3 即:mapreduce1的輸出是mapreduce2的輸入,mapreduce2的輸出式mapreduce3

2.線性表的儲存結構————單鏈表(思路分析C語言、C++完整程式)

目錄 1.單鏈表的基本概念 (1)單鏈表:當連結串列中的每個結點只含有一個指標域時,稱為單鏈表。 (2)頭指標:如上圖所示,連結串列中第一個結點的儲存位置叫做頭指標。 (3)頭結點:頭結點是放在第一個元素結點之前的結點,頭結點不是連結串列中的必

顯示原型和隱原型手繪原型原型是什麼?為什麼要有原型

顯式原型:prototype              隱式原型:__proto__1. 每個函式function都有一個prototype,即顯式原型(屬性)2. 每個例項物件都有一個__proto__,可稱為隱式原型(屬性)3. 物件的隱式原型的值為其對應建構函式的顯式原

php pdo類 防注入事務多庫自動選擇操作

因為某些原因目前業務不用框架開發,自己寫了一個pdo類實現防注入,事務等,後續還會繼續完善  <?php /*

區塊技術基礎原理與演算法(比特幣為例主要是比特幣的原理)密碼學原理

密碼學原理 對稱加密演算法 原理 對稱加密:使用同一金鑰進行加密和解密 傳統密碼加密,私鑰演算法加密,加密速度快,密文是緊湊的安全的 加密過程 A同學生成明文->通過私鑰和加密演算法->生成密文->將密文通過網路傳輸到目的地B同學->通過同一私鑰以及解密演算法->解密為明文 對稱

美的、京東備戰“紅六月”供應創新互利共贏

href 電商平臺 作用 供應鏈 alt 東家 中繼 提高效率 員工   為迎戰即將到來的“618全民年中購物節”,5月17日,美的集團副總裁王金亮一行來到京東總部,與京東商城家電事業部總裁閆小兵就雙方的戰略合作進行了全面深入的交流,並現場簽署了“紅六月”銷售任務書。 (