<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      深入理解 JavaScript 異步系列(2)—— jquery的解決方案

      第一部分,jQuery-1.5 之后的 ajax

      本地址 http://www.rzrgm.cn/wangfupeng1988/p/6515779.html 未經允許不得轉載~

      $.ajax這個函數各位應該都比較熟悉了,要完整的講解 js 的異步操作,就必須先從$.ajax這個方法說起。

      想要學到全面的知識,大家就不要著急,跟隨我的節奏來,并且相信我。我安排的內容,肯定都是有用的,對主題無用的東西,我不會拿來占用大家的時間。

      本節內容概述

      • 傳統的$.ajax
      • 1.5 版本之后的$.ajax
      • 改進之后的好處
      • 和后來的Promise的關系
      • 如何實現的?

      傳統的$.ajax

      先來一段最常見的$.ajax的代碼,當然是使用萬惡的callback方式

      var ajax = $.ajax({
          url: 'data.json',
          success: function () {
              console.log('success')
          },
          error: function () {
              console.log('error')
          }
      })
      
      console.log(ajax) // 返回一個 XHR 對象

      至于這么做會產生什么樣子的詬病,我想大家應該都很明白了。不明白的自己私下去查,但是你也可以繼續往下看,你只需要記住這樣做很不好就是了,要不然 jquery 也不會再后面進行改進

      1.5 版本之后的$.ajax

      但是從v1.5開始,以上代碼就可以這樣寫了:可以鏈式的執行done或者fail方法

      var ajax = $.ajax('data.json')
      ajax.done(function () {
              console.log('success 1')
          })
          .fail(function () {
              console.log('error')
          })
          .done(function () {
               console.log('success 2')
          })
      
      console.log(ajax) // 返回一個 deferred 對象

      大家注意看以上兩段代碼中都有一個console.log(ajax),但是返回值是完全不一樣的。

      • v1.5之前,返回的是一個XHR對象,這個對象不可能有done或者fail的方法的
      • v1.5開始,返回一個deferred對象,這個對象就帶有donefail的方法,并且是等著請求返回之后再去調用

      改進之后的好處

      這是一個標志性的改造,不管這個概念是誰最先提出的,它在 jquery 中首先大量使用并讓全球開發者都知道原來 ajax 請求還可以這樣寫。這為以后的Promise標準制定提供了很大意義的參考,你可以以為這就是后面Promise的原型。

      記住一句話————雖然 JS 是異步執行的語言,但是人的思維是同步的————因此,開發者總是在尋求如何使用邏輯上看似同步的代碼來完成 JS 的異步請求。而 jquery 的這一次更新,讓開發者在一定程度上得到了這樣的好處。

      之前無論是什么操作,我都需要一股腦寫到callback中,現在不用了。現在成功了就寫到done中,失敗了就寫到fail中,如果成功了有多個步驟的操作,那我就寫很多個done,然后鏈式連接起來就 OK 了。

      和后來的Promise的關系

      以上的這段代碼,我們還可以這樣寫。即不用donefail函數,而是用then函數。then函數的第一個參數是成功之后執行的函數(即之前的done),第二個參數是失敗之后執行的函數(即之前的fail)。而且then函數還可以鏈式連接。

      var ajax = $.ajax('data.json')
      ajax.then(function () {
              console.log('success 1')
          }, function () {
              console.log('error 1')
          })
          .then(function () {
              console.log('success 2')
          }, function () {
              console.log('error 2')
          })

      如果你對現在 ES6 的Promise有了解,應該能看出其中的相似之處。不了解也沒關系,你只需要知道它已經和Promise比較接近了。后面馬上會去講Promise

      如何實現的?

      明眼人都知道,jquery 不可能改變異步操作需要callback的本質,它只不過是自己定義了一些特殊的 API,并對異步操作的callback進行了封裝而已。

      那么 jquery 是如何實現這一步的呢?請聽下回分解!

       

      第二部分,jQuery deferred

      上一節講到 jquery v1.5 版本開始,$.ajax可以使用類似當前Promisethen函數以及鏈式操作。那么它到底是如何實現的呢?在此之前所用到的callback在這其中又起到了什么作用?本節給出答案

      本節使用的代碼參見這里

      本節內容概述

      • 寫一個傳統的異步操作
      • 使用$.Deferred封裝
      • 應用then方法
      • 有什么問題?

      寫一個傳統的異步操作

      給出一段非常簡單的異步操作代碼,使用setTimeout函數。

      var wait = function () {
          var task = function () {
              console.log('執行完成')
          }
          setTimeout(task, 2000)
      }
      wait()

      以上這些代碼執行的結果大家應該都比較明確了,即 2s 之后打印出執行完成但是我如果再加一個需求 ———— 要在執行完成之后進行某些特別復雜的操作,代碼可能會很多,而且分好幾個步驟 ———— 那該怎么辦? 大家思考一下!

      如果你不看下面的內容,而且目前還沒有Promise的這個思維,那估計你會說:直接在task函數中寫就是了!不過相信你看完下面的內容之后,會放棄你現在的想法。

      使用$.Deferred封裝

      好,接下來我們讓剛才簡單的幾行代碼變得更加復雜。為何要變得更加復雜?是因為讓以后更加復雜的地方變得簡單。這里我們使用了 jquery 的$.Deferred,至于這個是個什么鬼,大家先不用關心,只需要知道$.Deferred()會返回一個deferred對象,先看代碼,deferred對象的作用我們會面會說。

      function waitHandle() {
          var dtd = $.Deferred()  // 創建一個 deferred 對象
      
          var wait = function (dtd) {  // 要求傳入一個 deferred 對象
              var task = function () {
                  console.log('執行完成')
                  dtd.resolve()  // 表示異步任務已經完成
              }
              setTimeout(task, 2000)
              return dtd  // 要求返回 deferred 對象
          }
      
          // 注意,這里一定要有返回值
          return wait(dtd)
      }

      以上代碼中,又使用一個waitHandle方法對wait方法進行再次的封裝。waitHandle內部代碼,我們分步驟來分析。跟著我的節奏慢慢來,保證你不會亂。

      • 使用var dtd = $.Deferred()創建deferred對象。通過上一節我們知道,一個deferred對象會有done failthen方法(不明白的去看上一節)
      • 重新定義wait函數,但是:第一,要傳入一個deferred對象(dtd參數);第二,當task函數(即callback)執行完成之后,要執行dtd.resolve()告訴傳入的deferred對象,革命已經成功。第三;將這個deferred對象返回。
      • 返回wait(dtd)的執行結果。因為wait函數中返回的是一個deferred對象(dtd參數),因此wait(dtd)返回的就是dtd————如果你感覺這里很亂,沒關系,慢慢捋,一行一行看,相信兩三分鐘就能捋順!

      最后總結一下,waitHandle函數最終return wait(dtd)即最終返回dtd(一個deferred)對象。針對一個deferred對象,它有done failthen方法(上一節說過),它還有resolve()方法(其實和resolve相對的還有一個reject方法,后面會提到)

      應用then方法

      接著上面的代碼繼續寫

      var w = waitHandle()
      w.then(function () {
          console.log('ok 1')
      }, function () {
          console.log('err 1')
      }).then(function () {
          console.log('ok 2')
      }, function () {
          console.log('err 2')
      })

      上面已經說過,waitHandle函數最終返回一個deferred對象,而deferred對象具有done fail then方法,現在我們正在使用的是then方法。至于then方法的作用,我們上一節已經講過了,不明白的同學抓緊回去補課。

      執行這段代碼,我們打印出來以下結果。可以將結果對標以下代碼時哪一行。

      執行完成
      ok 1
      ok 2

      此時,你再回頭想想我剛才說提出的需求(要在執行完成之后進行某些特別復雜的操作,代碼可能會很多,而且分好幾個步驟),是不是有更好的解決方案了?

      有同學肯定發現了,代碼中console.log('err 1')console.log('err 2')什么時候會執行呢 ———— 你自己把waitHandle函數中的dtd.resolve()改成dtd.reject()試一下就知道了。

      • dtd.resolve() 表示革命已經成功,會觸發then中第一個參數(函數)的執行,
      • dtd.reject() 表示革命失敗了,會觸發then中第二個參數(函數)執行

      有什么問題?

      總結一下一個deferred對象具有的函數屬性,并分為兩組:

      • dtd.resolve dtd.reject
      • dtd.then dtd.done dtd.fail

      我為何要分成兩組 ———— 這兩組函數,從設計到執行之后的效果是完全不一樣的。第一組是主動觸發用來改變狀態(成功或者失敗),第二組是狀態變化之后才會觸發的監聽函數。

      既然是完全不同的兩組函數,就應該徹底的分開,否則很容易出現問題。例如,你在剛才執行代碼的最后加上這么一行試試。

      w.reject()

      那么如何解決這一個問題?請聽下回分解!

       

      第三部分,jQuery promise

      上一節通過一些代碼演示,知道了 jquery 的deferred對象是解決了異步中callback函數的問題,但是

      本節使用的代碼參見這里

      本節內容概述

      • 返回promise
      • 返回promise的好處
      • promise 的概念

      返回promise

      我們對上一節的的代碼做一點小小的改動,只改動了一行,下面注釋。

      function waitHandle() {
          var dtd = $.Deferred()
          var wait = function (dtd) {
              var task = function () {
                  console.log('執行完成')
                  dtd.resolve()
              }
              setTimeout(task, 2000)
              return dtd.promise()  // 注意,這里返回的是 primise 而不是直接返回 deferred 對象
          }
          return wait(dtd)
      }
      
      var w = waitHandle() // 經過上面的改動,w 接收的就是一個 promise 對象
      $.when(w)
       .then(function () {
          console.log('ok 1')
       })
       .then(function () {
          console.log('ok 2')
       })

      改動的一行在這里return dtd.promise(),之前是return dtddtd是一個deferred對象,而dtd.promise就是一個promise對象。

      promise對象和deferred對象最重要的區別,記住了————promise對象相比于deferred對象,缺少了.resolve.reject這倆函數屬性。這么一來,可就完全不一樣了。

      上一節我們提到一個問題,就是在程序的最后一行加一句w.reject()會導致亂套,你現在再在最后一行加w.reject()試試 ———— 保證亂套不了 ———— 而是你的程序不能執行,直接報錯。因為,wpromise對象,不具備.reject屬性。

      返回promise的好處

      上一節提到deferred對象有兩組屬性函數,而且提到應該把這兩組徹底分開。現在通過上面一行代碼的改動,就分開了。

      • waitHandle函數內部,使用dtd.resolve()來該表狀態,做主動的修改操作
      • waitHandle最終返回promise對象,只能去被動監聽變化(then函數),而不能去主動修改操作

      一個“主動”一個“被動”,完全分開了。

      promise 的概念

      jquery v1.5 版本發布時間距離現在(2017年初春)已經老早之前了,那會兒大家網頁標配都是 jquery 。無論里面的deferredpromise這個概念和想法最早是哪位提出來的,但是最早展示給全世界開發者的是 jquery ,這算是Promise這一概念最先的提出者。

      其實本次課程主要是給大家分析 ES6 的Promise Generatorasync-await,但是為何要從 jquery 開始(大家現在用 jquery 越來越少)?就是要給大家展示一下這段歷史的一些起點和發展的知識。有了這些基礎,你再去接受最新的概念會非常容易,因為所有的東西都是從最初順其自然發展進化而來的,我們要去用一個發展進化的眼光學習知識,而不是死記硬背。

      求打賞

      如果你看完了,感覺還不錯,歡迎給我打賞 ———— 以激勵我更多輸出優質內容

      最后,github地址是 https://github.com/wangfupeng1988/js-async-tutorial 歡迎 star 和 pr

      -------

      學習作者教程:《前端JS高級面試》《前端JS基礎面試題》《React.js模擬大眾點評webapp》《zepto設計與源碼分析》《json2.js源碼解讀

      posted @ 2017-03-08 08:13  王福朋  閱讀(13345)  評論(4)    收藏  舉報
      主站蜘蛛池模板: 天天综合亚洲色在线精品| 午夜福利国产一区二区三区| 99亚洲男女激情在线观看| 无码国内精品人妻少妇| 人妻中文字幕亚洲精品| 在线观看无码av五月花| 国产成人高清亚洲综合| 真人作爱免费视频| 亚洲丰满熟女一区二区蜜桃| 久热天堂在线视频精品伊人| 国产精品久久久久久免费软件| 亚洲最大成人免费av| 久久亚洲精品天天综合网| 中文字幕日韩有码一区| 中文字幕日韩精品一区二区三区| 国产婷婷综合在线视频中文| 亚洲精品国产综合麻豆久久99| 亚洲欧美日韩综合一区在线| 亚州中文字幕一区二区| 部精品久久久久久久久| 中文字幕无码av不卡一区| 好湿好紧太硬了我太爽了视频| 国产av一区二区久久蜜臀| 夜夜嗨久久人成在日日夜夜| 2022亚洲男人天堂| 欧美极品色午夜在线视频| 国产精品爽爽久久久久久竹菊| 91精品国产老熟女在线| 少妇人妻真实偷人精品| 少妇午夜福利一区二区三区 | 国产不卡一区二区精品| 欧美国产日韩久久mv| 亚洲男人电影天堂无码| 在线播放国产女同闺蜜| 美女自卫慰黄网站| 精品无码人妻一区二区三区 | 无码国产精品一区二区VR老人| 少妇无码av无码一区| 亚洲精品视频一二三四区| 国产精品免费看久久久| 无码伊人久久大杳蕉中文无码|