jquery的上帝視角(promise)

Paste_Image.png

promise 是一種異步編程規範,音譯來理解——「普羅米修斯」。普羅米修斯是希臘神話故事中的英雄,名字的意思是「先知」。Promise最初的命名是Futures, 「將來」,可見Promise含義不是字面的「誓言」「承諾」之類,而是「先知」「將來」的意思。javascript

promise的出現是爲了解決 異步編程中最頭疼的事情 回調嵌套地域html

動畫回調金字塔:java

$('xx').animate({}, function(){
    //do something
    $('xx').animate({},function(){
        //do something
        $('xx').animate({},function(){
            //do something
            $('xx').animate({},function(){
                //do something
                $('xx').animate({},function(){
                    //do something
                },1000);
            },1000);
        },1000);
    },1000);
},1000);

看到這樣的代碼,其實強迫症已經犯了. 以上就是 從代碼的視角去看問題.jquery

好了如今咱們換個角度 去看這個問題. 切換到上帝視角git

$('xx').animate({})
    //動畫1 以後
    .then(function(){
        return $('xx').animate({});
    })
    //動畫2 以後
    .then(function(){
        return  $('xx').animate({});
    })
    //動畫3 以後
    .then(function(){
        return  $('xx').animate({});
    })
    //動畫4 以後
    .then(function(){
        return  $('xx').animate({});
    })
    //動畫完成
    .done(function(){
        console.log("動畫完成...")
    })
    //動畫失敗
    .fail(function(){
        console.log("動畫出錯...")
    });

是否是很是 清晰流暢 這就是 同步編寫異步執行 所帶來的魅力es6

這種模式被稱做promise模式 咱們能夠理解爲
現實世界裏,時間這條線就是單線程的,不會出現兩條時間線,這種事是會出如今科幻故事裏. 若是咱們的 人生 = 代碼
那麼上帝已經在他的時間維度的一瞬間規劃好了你的一輩子(由於他有先知的能力)(他無需跟着經歷你的時間),雖然你本身依然感覺到了時間,以及各類變數github

更多詳細代碼哲學 請看這篇文章
http://www.zhangxinxu.com/wor...編程

現實中的例子 :
你求 別人辦事 別人給了你句答覆20分鐘後 來拿結果 這個答覆 就是 promise 在20分鐘內 你能夠去作別的事情 20分鐘後你拿這個promise 找到那我的 兌現承諾.api

promise 就是將來的值promise

在jq中 提供的$.deferred對象 就是實現promise的解決方案.,defer的意思是"延遲",因此deferred對象的含義就是"延遲"到將來某個點再執行。

deferred對象有三種執行狀態

  1. 未完成(notify)
  2. 已完成(resolve)
  3. 已失敗(reject)

當deferred對象狀態發生變化 好比

  1. 變成resolve deferred對象馬上調用done()方法指定的回調函數
  2. 變成reject調用fail()方法指定的回調函數;
  3. 變成 notify 則繼續等待,或者調用progress()方法指定的回調函數

這是不能直接 返回deferred對象 由於這個deferred對象 能夠隨意被修改狀態,所以我門須要返回一個 不能修改狀態的promise
deferred.promise() : 返回一個新的deferred對象,該對象的運行狀態沒法被改變

因此咱們的promise規範的模版

//建立
var  fnxx = function(){

    var defer = $.Deferred();

    //業務代碼....

    //條件
    if(xxxx)
        //成功
        defer.resolve(//成功返回值);
    else
        //失敗
        defer.reject(//失敗返回error);


    return defer.promise();
}


//調用
fnxx()
    .done(function(success){

    })
    .fail(function(error){
        
    });

業務案例

有以下需求

  1. 登陸得到token
  2. 根據token查詢用戶信息
  3. 根據userId查詢用戶積分
  4. 根據積分判斷用戶是否須要充值

代碼以下 :

//登陸得到token
            login(userName,passWord)

                    //得到用戶信息(根據token)
                    .then(function(loginUser){
                        return getUserInfo(loginUser.token);
                    })

                      //得到積分(根據用戶id)
                    .then(function(userInfo){
                        return getCredit(userInfo.userId);
                    })

                    //是否須要充值
                    .then(function(credit){
                        return isRecharge(credit);
                    })
                     //最後結果
                    .done(function(isRe){
                        console.log(isRe);
                        if(isRe == 0){
                            alert("不須要充值!");
                        }
                        else if(isRe == 1){
                            alert("請充值");
                        }
                        else{
                            console.log("錯誤!");
                        }
                    })
                    //任意一步 出現錯誤
                    .fail(function(ob,name,error){
                        console.error(error.stack);
                    });

業務邏輯清晰天然 咱們必需要學會 站在上帝視角 審視它們. 只有這樣才能輕鬆駕馭它們 成爲Dominate

源代碼git https://github.com/sherlock22...

參考
http://www.ruanyifeng.com/blo...
http://www.zhangxinxu.com/wor...

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息