茄子在线看片免费人成视频,午夜福利精品a在线观看,国产高清自产拍在线观看,久久综合久久狠狠综合

    <s id="ddbnn"></s>
  • <sub id="ddbnn"><ol id="ddbnn"></ol></sub>

  • <legend id="ddbnn"></legend><s id="ddbnn"></s>

    詳解JavaScript異步編程中jQuery的promise對象的作用
    來源:易賢網(wǎng) 閱讀:1013 次 日期:2016-07-06 10:40:31
    溫馨提示:易賢網(wǎng)小編為您整理了“詳解JavaScript異步編程中jQuery的promise對象的作用”,方便廣大網(wǎng)友查閱!

    這篇文章主要介紹了JavaScript異步編程中jQuery的promise對象的作用,同時也談到了js的Dojo框架中promise模式的實現(xiàn),需要的朋友可以參考下

    Promise, 中文可以理解為愿望,代表單個操作完成的最終結(jié)果。一個Promise擁有三種狀態(tài):分別是unfulfilled(未滿足的)、fulfilled(滿足的)、failed(失敗的),fulfilled狀態(tài)和failed狀態(tài)都可以被監(jiān)聽。一個愿望可以從未滿足狀態(tài)變?yōu)闈M足或者失敗狀態(tài),一旦一個愿望處于滿足或者失敗狀態(tài),其狀態(tài)將不可再變化。這種“不可改變”的特性對于一個Promise來說非常的重要,它可以避免Promise的狀態(tài)監(jiān)聽器修改一個Promise的狀態(tài)導(dǎo)致別的監(jiān)聽器的行為異常。例如:一個監(jiān)聽fulfilled狀態(tài)的監(jiān)聽器把Promise的狀態(tài)修改為failed,那么將觸發(fā)failed狀態(tài)的監(jiān)聽器,而如果一個failed狀態(tài)監(jiān)聽器又把Promise的狀態(tài)設(shè)置為fulfilled,那么又將觸發(fā)fulfilled狀態(tài)的監(jiān)聽器,這樣將導(dǎo)致死循環(huán)。另外一種理解Promise這種特性的方式是把Promise看成是javascript中的primative類型的變量,這種變量可以被傳入被調(diào)用的函數(shù)中,但是不可以被調(diào)用函數(shù)所改變。

    每一個Promise對象都有一個方法:then(fulfilledHandler, errorHandler, progressHandler),用于監(jiān)聽一個Promise的不同狀態(tài)。fulfilledHandler用于監(jiān)聽fulfilled事件,errorHandler用于監(jiān)聽failed事件,progressHandler用于監(jiān)聽progress事件。一個Promise不強制實現(xiàn)progress狀態(tài)的事件監(jiān)聽(jQuery的Deferred就是一個Promise的實現(xiàn),但沒有實現(xiàn)對progress狀態(tài)事件的處理)。

    then(...)函數(shù)中的fulfilledHandler和errorHandler的返回值是一個新的Promise對象, 以便能夠鏈式調(diào)用then(...)函數(shù)。每一個回調(diào)函數(shù)在正常情況下返回的是處于fulfilled狀態(tài)的Promise,如果該回調(diào)函數(shù)返回錯誤值,那么返回的Promise狀態(tài)將會變?yōu)閒ailed。

    promise在異步編程中的作用

    異步模式在web編程中變得越來越重要,對于web主流語言Javascript來說,這種模式實現(xiàn)起來不是很利索,為此,許多Javascript庫(比如 jQuery和Dojo)添加了一種稱為promise的抽象(有時也稱之為deferred)。通過這些庫,開發(fā)人員能夠在實際編程中使用 promise模式。

    隨著Web 2.0技術(shù)的深入,瀏覽器端承受了越來越多的計算壓力,所以“并發(fā)”具有積極的意義。對于開發(fā)人員來說,既要保持頁面與用戶的交互不受影響,又要協(xié)調(diào)頁面與異步任務(wù)的關(guān)系,這種非線性執(zhí)行的編程要求存在適應(yīng)的困難。先拋開頁面交互不談,我們能夠想到對于異步調(diào)用需要處理兩種結(jié)果——成功操作和失敗處理。在成功的調(diào)用后,我們可能需要把返回的結(jié)果用在另一個Ajax請求中,這就會出現(xiàn)“函數(shù)連環(huán)套”的情況。這種情況會造成編程的復(fù)雜性??纯聪旅娴拇a示例(基于XMLHttpRequest2):

    function searchTwitter(term, onload, onerror) {

       var xhr, results, url;

       url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;

       xhr = new XMLHttpRequest();

       xhr.open('GET', url, true);

       xhr.onload = function (e) {

         if (this.status === 200) {

           results = JSON.parse(this.responseText);

           onload(results);

         }

       };

       xhr.onerror = function (e) {

         onerror(e);

       };

       xhr.send();

     }

     function handleError(error) {

       /* handle the error */

     }

     function concatResults() {

       /* order tweets by date */

     }

     function loadTweets() {

       var container = document.getElementById('container');

       searchTwitter('#IE10', function (data1) {

         searchTwitter('#IE9', function (data2) {

           /* Reshuffle due to date */

           var totalResults = concatResults(data1.results, data2.results);

           totalResults.forEach(function (tweet) {

             var el = document.createElement('li');

             el.innerText = tweet.text;

             container.appendChild(el);

           });

         }, handleError);

       }, handleError);

     }

    上面的代碼其功能是獲取Twitter中hashtag為IE10和IE9的內(nèi)容并在頁面中顯示出來。這種嵌套的回調(diào)函數(shù)難以理解,開發(fā)人員需要仔細分析哪些代碼用于應(yīng)用的業(yè)務(wù)邏輯,而哪些代碼處理異步函數(shù)調(diào)用的,代碼結(jié)構(gòu)支離破碎。錯誤處理也分解了,我們需要在各個地方檢測錯誤的發(fā)生并作出相應(yīng)的處理。

    為了降低異步編程的復(fù)雜性,開發(fā)人員一直尋找簡便的方法來處理異步操作。其中一種處理模式稱為promise,它代表了一種可能會長時間運行而且不一定必須完整的操作的結(jié)果。這種模式不會阻塞和等待長時間的操作完成,而是返回一個代表了承諾的(promised)結(jié)果的對象。

    考慮這樣一個例子,頁面代碼需要訪問第三方的API,網(wǎng)絡(luò)延遲可能會造成響應(yīng)時間較長,在這種情況下,采用異步編程不會影響整個頁面與用戶的交互。promise模式通常會實現(xiàn)一種稱為then的方法,用來注冊狀態(tài)變化時對應(yīng)的回調(diào)函數(shù)。比如下面的代碼示例:

    searchTwitter(term).then(filterResults).then(displayResults);

    promise模式在任何時刻都處于以下三種狀態(tài)之一:未完成(unfulfilled)、已完成(resolved)和拒絕(rejected)。以CommonJS Promise/A 標準為例,promise對象上的then方法負責添加針對已完成和拒絕狀態(tài)下的處理函數(shù)。then方法會返回另一個promise對象,以便于形成promise管道,這種返回promise對象的方式能夠支持開發(fā)人員把異步操作串聯(lián)起來,如then(resolvedHandler, rejectedHandler); 。resolvedHandler 回調(diào)函數(shù)在promise對象進入完成狀態(tài)時會觸發(fā),并傳遞結(jié)果;rejectedHandler函數(shù)會在拒絕狀態(tài)下調(diào)用。

    有了promise模式,我們可以重新實現(xiàn)上面的Twitter示例。為了更好的理解實現(xiàn)方法,我們嘗試著從零開始構(gòu)建一個promise模式的框架。首先需要一些對象來存儲promise。

    var Promise = function () {

        /* initialize promise */

      };

    接下來,定義then方法,接受兩個參數(shù)用于處理完成和拒絕狀態(tài)。

    Promise.prototype.then = function (onResolved, onRejected) {

       /* invoke handlers based upon state transition */

     };

    同時還需要兩個方法來執(zhí)行理從未完成到已完成和從未完成到拒絕的狀態(tài)轉(zhuǎn)變。

    Promise.prototype.resolve = function (value) {

       /* move from unfulfilled to resolved */

     };

     Promise.prototype.reject = function (error) {

       /* move from unfulfilled to rejected */

     };

    現(xiàn)在搭建了一個promise的架子,我們可以繼續(xù)上面的示例,假設(shè)只獲取IE10的內(nèi)容。創(chuàng)建一個方法來發(fā)送Ajax請求并將其封裝在promise中。這個promise對象分別在xhr.onload和xhr.onerror中指定了完成和拒絕狀態(tài)的轉(zhuǎn)變過程,請注意searchTwitter函數(shù)返回的正是promise對象。然后,在loadTweets中,使用then方法設(shè)置完成和拒絕狀態(tài)對應(yīng)的回調(diào)函數(shù)。

    function searchTwitter(term) {

      var url, xhr, results, promise;

      url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;

      promise = new Promise();

      xhr = new XMLHttpRequest();

      xhr.open('GET', url, true);

      xhr.onload = function (e) {

        if (this.status === 200) {

          results = JSON.parse(this.responseText);

          promise.resolve(results);

        }

      };

      xhr.onerror = function (e) {

        promise.reject(e);

      };

      xhr.send();

      return promise;

    }

    function loadTweets() {

      var container = document.getElementById('container');

      searchTwitter('#IE10').then(function (data) {

        data.results.forEach(function (tweet) {

          var el = document.createElement('li');

          el.innerText = tweet.text;

          container.appendChild(el);

        });

      }, handleError);

    }

    到目前為止,我們可以把promise模式應(yīng)用于單個Ajax請求,似乎還體現(xiàn)不出promise的優(yōu)勢來。下面來看看多個Ajax請求的并發(fā)協(xié)作。此時,我們需要另一個方法when來存儲準備調(diào)用的promise對象。一旦某個promise從未完成狀態(tài)轉(zhuǎn)化為完成或者拒絕狀態(tài),then方法里對應(yīng)的處理函數(shù)就會被調(diào)用。when方法在需要等待所有操作都完成的時候至關(guān)重要。

    Promise.when = function () {

      /* handle promises arguments and queue each */

    };

    以剛才獲取IE10和IE9兩塊內(nèi)容的場景為例,我們可以這樣來寫代碼:

    var container, promise1, promise2;

    container = document.getElementById('container');

    promise1 = searchTwitter('#IE10');

    promise2 = searchTwitter('#IE9');

    Promise.when(promise1, promise2).then(function (data1, data2) {

      /* Reshuffle due to date */

      var totalResults = concatResults(data1.results, data2.results);

      totalResults.forEach(function (tweet) {

        var el = document.createElement('li');

        el.innerText = tweet.text;

        container.appendChild(el);

      });

    }, handleError);

    分析上面的代碼可知,when函數(shù)會等待兩個promise對象的狀態(tài)發(fā)生變化再做具體的處理。在實際的Promise庫中,when函數(shù)有很多變種,比如 when.some()、when.all()、when.any()等,讀者從函數(shù)名字中大概能猜出幾分意思來,詳細的說明可以參考CommonJS的一個promise實現(xiàn)when.js。

    除了CommonJS,其他主流的Javascript框架如jQuery、Dojo等都存在自己的promise實現(xiàn)。開發(fā)人員應(yīng)該好好利用這種模式來降低異步編程的復(fù)雜性。我們選取Dojo為例,看一看它的實現(xiàn)有什么異同。

    Dojo框架里實現(xiàn)promise模式的對象是Deferred,該對象也有then函數(shù)用于處理完成和拒絕狀態(tài)并支持串聯(lián),同時還有resolve和reject,功能如之前所述。下面的代碼完成了Twitter的場景:

    function searchTwitter(term) {

      var url, xhr, results, def;

      url = 'http://search.twitter.com/search.json?rpp=100&q=' + term;

      def = new dojo.Deferred();

      xhr = new XMLHttpRequest();

      xhr.open('GET', url, true);

      xhr.onload = function (e) {

        if (this.status === 200) {

          results = JSON.parse(this.responseText);

          def.resolve(results);

        }

      };

      xhr.onerror = function (e) {

        def.reject(e);

      };

      xhr.send();

      return def;

    }

    dojo.ready(function () {

      var container = dojo.byId('container');

      searchTwitter('#IE10').then(function (data) {

        data.results.forEach(function (tweet) {

          dojo.create('li', {

            innerHTML: tweet.text

          }, container);

        });

      });

    });

    不僅如此,類似dojo.xhrGet方法返回的即是dojo.Deferred對象,所以無須自己包裝promise模式。

    var deferred = dojo.xhrGet({

      url: "search.json",

      handleAs: "json"

    });

    deferred.then(function (data) {

      /* handle results */

    }, function (error) {

      /* handle error */

    });

    除此之外,Dojo還引入了dojo.DeferredList,支持開發(fā)人員同時處理多個dojo.Deferred對象,這其實就是上面所提到的when方法的另一種表現(xiàn)形式。

    dojo.require("dojo.DeferredList");

    dojo.ready(function () {

      var container, def1, def2, defs;

      container = dojo.byId('container');

      def1 = searchTwitter('#IE10');

      def2 = searchTwitter('#IE9');

      defs = new dojo.DeferredList([def1, def2]);

      defs.then(function (data) {

        // Handle exceptions

        if (!results[0][0] || !results[1][0]) {

          dojo.create("li", {

            innerHTML: 'an error occurred'

          }, container);

          return;

        }

        var totalResults = concatResults(data[0][1].results, data[1][1].results);

        totalResults.forEach(function (tweet) {

          dojo.create("li", {

            innerHTML: tweet.text

          }, container);

        });

      });

    });

    上面的代碼比較清楚,不再詳述。

    說到這里,讀者可能已經(jīng)對promise模式有了一個比較完整的了解,異步編程會變得越來越重要,在這種情況下,我們需要找到辦法來降低復(fù)雜度,promise模式就是一個很好的例子,它的風格比較人性化,而且主流的JS框架提供了自己的實現(xiàn)。所以在編程實踐中,開發(fā)人員應(yīng)該嘗試這種便捷的編程技巧。需要注意的是,promise模式的使用需要恰當?shù)卦O(shè)置promise對象,在對應(yīng)的事件中調(diào)用狀態(tài)轉(zhuǎn)換函數(shù),并且在最后返回promise對象。

    更多信息請查看網(wǎng)絡(luò)編程
    易賢網(wǎng)手機網(wǎng)站地址:詳解JavaScript異步編程中jQuery的promise對象的作用

    2026上岸·考公考編培訓(xùn)報班

    • 報班類型
    • 姓名
    • 手機號
    • 驗證碼
    關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
    工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
    聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)