国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

學習promise編寫和使用

aaron / 1537人閱讀

摘要:實現是中的一種異步編程實現方式,中異步編程主要是指瀏覽器事件處理,等,通過傳入回調函數來實現控制反轉。對象符合編程規范,目的是為異步編程提供統一接口,它最大的優點就是避免了回調金字塔。

promise實現

Promise是Javascript中的一種異步編程實現方式,js中異步編程主要是指瀏覽器DOM事件處理,setTimeout/setInterval,ajax等,通過傳入回調函數來實現控制反轉。Promsie對象符合CommonJS編程規范,目的是為異步編程提供統一接口,它最大的優點就是避免了回調金字塔。
假設要實現一個用戶展示的任務,任務分為三步:

獲取用戶信息

獲取用戶圖片

彈窗提示
一般之前使用方式為:

之前已經對getUserInfo()getUserImage(),showTip()方法進行了定義

getUserInfo(id, function(info){
    getUserImage(info.img, function(){
        showTip();
    })
})

如果回調函數不止3個,那將會是一個非常長的回調,換成Promise實現:

//getUserInfo返回promise
getUserInfo(id)
    .then(getUserImage)
    .then(showTip)
    .catch(function(e){
        console.log(e);
    });

簡單的講,Promsie的思想就是每一個異步任務返回一個promise對象,該對象有一個then方法,允許指定回調函數。這里getUserInfo的回調函數就是getUserImage

getUserInfo函數要進行如下改寫(這里用jQuery的Deferred()實現)

function getUserInfo(id){
    var dfd = $.Deferred();
    setTimeout(function(){
        //獲取用戶信息
        dfd.resolve();
    }, 500);

    return dfd.promise;
}

這樣一種寫法回調函數就成了鏈式寫法,程序的流程非常清楚,可以實現多個回調。
先在ES6出來之后,許多瀏覽器已經支持Promise方法,

promise有三種狀態:

pending:初始狀態

fulfilled:成功操作

rejected:失敗操作
開始的時候promise是pending狀態,fulfill之后就會執行回調then的回調函數,如果是reject就會調用catch進行異常處理,Promise.prototype.then() Promise.prototype.catch() 兩種方法狀態都會返回一個promise對象,用于后續鏈式調用。

建立一個promise例子
    
    
  "use strict";
var promiseCount = 0;

function testPromise(){
    var thisPromiseCount = promiseCount++;
    var log = document.getElementById("log");
    log.insertAdjacentHTML("beforeend", thisPromiseCount + 
        ") 開始 (異步調用開始)
"); //新建一個promsie對象 var p1 = new Promise(function(resolve, reject){ log.insertAdjacentHTML("beforeend", thisPromiseCount + ") Promise 開始執行 (異步調用開始)
"); window.setTimeout(function(){ resolve(thisPromiseCount); }, 2000) }); //定義promise執行fulfilled執行的then()回調函數以及執行reject后的catch回調函數 p1.then( function(val) { log.insertAdjacentHTML("beforeend", val + ") Promise fulfilled (異步代碼中斷)
"); }) .catch( function(reason) { console.log("Handle rejected promise ("+reason+") here."); }); log.insertAdjacentHTML("beforeend", thisPromiseCount + ") 建立promise"); }if ("Promise" in window) { var btn = document.getElementById("btn"); btn.addEventListener("click",testPromise); } else { log = document.getElementById("log"); log.innerHTML = "瀏覽器不支持promise接口"; } }

單擊按鈕后,首先執行promise

3秒之后resolve調用then()方法

實現XMLHttpRequest獲取數據

使用ajax異步加載圖片

  function imgLoad(url) {
    //返回promsie對象
    return new Promise(function(resolve, reject) {
      var xhr = new XMLHttpRequest();
      xhr.open("GET", url);
      xhr.responseType = "blob";
      xhr.onload = function() {
        if (xhr.status === 200) {
          resolve(xhr.response);
        } else {
          reject(Error("圖像加載失敗; 錯誤原因:" + xhr.statusText));
        }
      };
      xhr.onerror = function() {
          reject(Error("加載錯誤."));
      };
      xhr.send();
    });
  }
  
  var body = document.querySelector("body");
  var myImage = new Image();
  var url = "http://7qnb7a.com1.z0.glb.clouddn.com/6608717992840918931.jpg";

  imgLoad(url).then(function(response) {
     var imageURL = window.URL.createObjectURL(response);
     myImage.src = imageURL;
     body.appendChild(myImage);
  }, function(Error) {
    console.log(Error);
  });

構建一個簡單的promise模式框架

首先需要建立一個對象來存儲promise

Promise = function(){
    this.queue = [];
    this.value = null;
    this.status = "pending";
};

定義獲取隊列,設定狀態和獲取狀態原型方法

Promsie.prototype.getQueue = function(){
    return this.queue;
};
Promise.prototype.getStatus = function(){
    return this.status;
};
Promise.prototype.setStatus = function(s, value){
    if(s === "fulfilled" || s === "rejected"){
        this.status = s;
        this.value = value || null;
        this.queue = [];
        var freezeObject = Object.freeze || function(){};
        freezeObject(this);
    }else{
        throw new Error({message:"doesn"t support status: "+s});
    }
};

定義then方法,接受兩個參數用于完成和拒絕任務操作。

Promise.prototype.then = function(onFulfilled, onRejected){
    var handler = {
        "fulfilled": onFulfilled,
        "rejected": onRejected
    };
    handler.deferred = new Deferred();
    if(!this.isPending()){
        utils.procedure(this.status, handler, this.value);
    }else{
        this.queue.push(handler);
    }
    return handler.deferred.promise;
};

定義三個不同狀態函數

Promise.prototype.isFulfilled = function(){
    return this.status === "fulfilled";
};
Promise.prototype.isRejected = function(){
    return this.status === "rejected";
};
Promise.prototype.isPending = function(){
    return this.status === "pending";
};

工具處理函數

var utils = (function(){
    var makeSignaler = function(deferred, type){
        return function(result){
            transition(deferred, type, result);
        }
    };
    
    var procedure = function(type, handler, result){
        var func = handler[type];
        var def = handler.deferred;
        if(func){
            try{
                var newResult = func(result);
                if(newResult && typeof newResult.then === "function"){
                    newResult.then(makeSignaler(def, "fulfilled"), makeSignaler(def, "rejected"));
                }else{transition(def, type, newResult);}
            }catch(err){transition(def, "rejected", err);}
        }else{transition(def, type, result);}
    };

    var transition = function(deferred, type, result){
        if(type === "fulfilled"){
            deferred.resolve(result);
        }else if(type === "rejected"){
            deferred.reject(result);
        }else if(type !== "pending"){
            throw new Error({"messgae":"doesn,t support type:"+type});
        } 
    };

    return {
        "procedure": procedure
    }
})();

定義延遲函數

Deferred = function() {
    this.promise = new Promise();
};

Deferred.prototype.resolve = function(result) {
    if (!this.promise.isPending()) {
        return;
    }

    var queue = this.promise.getQueue();
    for (var i = 0, len = queue.length; i < len; i++) {
        utils.procedure("fulfilled", queue[i], result);
    }
    this.promise.setStatus("fulfilled", result);
};

Deferred.prototype.reject = function(err) {
    if (!this.promise.isPending()) {
        return;
    }

    var queue = this.promise.getQueue();
    for (var i = 0, len = queue.length; i < len; i++) {
        utils.procedure("rejected", queue[i], err);
    }
    this.promise.setStatus("rejected", err);
}

有很多實現了promises的庫供開發者可用。 像jQuery的 Deferred, 微軟的 WinJS.Promise, when.js, q, 和dojo.Deferred.
關于jQuery的Deferred可以參考jQuery的deferred對象詳解

Promise MDN

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79070.html

相關文章

  • ES2017異步函數現已正式可用

    摘要:標準已于年月份正式定稿了,并廣泛支持最新的特性異步函數。為了領會,我們需要回到普通回調函數中進一步學習。從此編寫回調函數不再那么痛苦。回調是一個函數,可以將結果傳遞給函數并在該函數內進行調用,以便作為事件的響應。 ES2017標準已于2017年6月份正式定稿了,并廣泛支持最新的特性:異步函數。如果你曾經被異步 JavaScript 的邏輯困擾,這么新函數正是為你設計的。 異步函數或多或...

    android_c 評論0 收藏0
  • 自動化測試(未完,后續學習之后會補充更具體的)

    摘要:斷言斷言是什么模塊提供了一組簡單的斷言測試,可用于測試不變量。環境是他們不必設置大量配置的環境,而是開發人員可以編寫代碼并從測試中獲得即時反饋的地方。每當測試時,結果將出現在您的拉取請求中,您的歷史記錄將在其控制面板中提供。 Node assert (斷言) 斷言是什么 assert 模塊提供了一組簡單的斷言測試,可用于測試不變量。 存在嚴格模式(strict)和遺留模式(legacy...

    姘存按 評論0 收藏0
  • 【全文】狼叔:如何正確的學習Node.js

    摘要:感謝大神的免費的計算機編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學習簡介現在,越來越多的科技公司和開發者開始使用開發各種應用。 說明 2017-12-14 我發了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當不錯的,甚至連著名的hax賀老都很認同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很...

    Edison 評論0 收藏0
  • 【全文】狼叔:如何正確的學習Node.js

    摘要:感謝大神的免費的計算機編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學習簡介現在,越來越多的科技公司和開發者開始使用開發各種應用。 說明 2017-12-14 我發了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當不錯的,甚至連著名的hax賀老都很認同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很...

    fengxiuping 評論0 收藏0

發表評論

0條評論

aaron

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<