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

資訊專欄INFORMATION COLUMN

只為那句承諾-大話Promise

EastWoodYang / 2386人閱讀

摘要:什么是是異步編程的一種解決方案,比傳統的解決方案回調函數和事件更合理和更強大。函數可以將狀態轉變為狀態。對象通過方法來添加回調函數。當發生錯誤的時候可以通過方法,來定義回調函數。接受數組作為參數傳入,每個元素都是一個對象。

大家周末好,要說最近幾年什么語言大紅大紫,當屬JavaScript了。話說雖然是10天就創造出的語言,但是人家能文能武。web前端自然不必多說了,各種框架你方登罷我上場,前兩年還是Angular一統天下,這兩年React又是大紅大紫,還有Vue最近異軍突起,好不紅火。要是僅僅是前端也就算了,但是由于Node.js人家在后臺也能寫,React Native的出現讓人家移動端也能做。好吧,還有硬件上也出現Ruff方案,好像硬件上也能寫了。真是讓人感覺挺有意思的事情。

圖表君上邊叨叨了這么多,難道是為JavaScript唱贊歌的嗎?呵呵,其實并不是。只是最近因為在用上篇文章介紹的AWS Lambda。Lambda現在只支持Java,Node.js,Python。最終選擇了Node.js進行開發,不可避免的要牽扯到異步操作的問題。那么今天就來聊聊JavaScript中的Promise。

什么是Promise

Promise是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最早提出和實現,ES6將其寫進了語言標準,統一了用法,原生提供了Promise對象。

所謂Promise,簡單說就是一個容器,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說,Promise是一個對象,從它可以獲取異步操作的消息。Promise提供統一的API,各種異步操作都可以用同樣的方法進行處理。

上面是Promise的一個定義,引自阮一峰的ES6標準入門一書。S6標準入門。多說一句,目前的JavaScript項目無論是前臺或者是后臺,都應該采用ES6的標準語法來寫,ES6讓JavaScript的書寫更加的清晰和規范。

基本用法

如何來構造一個promise對象呢?ES6中提供了原生Promise可以使用。

var promise = new Promise(function(resolve, reject) {
  // ... here is some code

  if (/* 異步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

上面的例子給出了new一個promise對象的方法,Promise的構造函數接受一個函數作為參數傳入,這個函數的兩個參數,reject和resolve是JavaScript本身提供的兩個函數。
一個promise對象有三個狀態分別是,pending,resolved,rejected。resolve函數可以將pending狀態轉變為resolved狀態。reject函數可以講pending狀態轉變了rejected狀態。對象的狀態不受外界的影響,同樣也是promise名字的由來。外部你拿著我的一個承諾,一會我會告訴你我的狀態。

promise對象通過then方法來添加回調函數。例如這樣

promise.then(data=> console.log(data), err=> console.log(err));

當promise被resolved的時候,就會把data log出來。當promise被rejected的時候,err就會被log出來。
看上去好像是挺簡單的,的確Promise的應用使得異步的操作,以同步的形式表現出來。當發生錯誤的時候可以通過catch方法,來定義回調函數。

怎么用

上邊都是一些干巴巴的定義,那么到底該怎么用呢?Promise又怎么樣的解決了問題呢,下邊我們看一個例子。假設下邊一個場景,我們一個服務,從一個外邊service獲取數據,然后寫到一個db里,或者一個存儲里,最后在把存儲的狀態龍出來,那么如果沒有promise是怎么寫的呢?可能會是這樣。

getData(function (value1) {
  storeToDb(value1, function(value2) {
    logStore(value2, function(value3) {
      //...
    });
  });
});

傳統的回調的寫法,這樣使得代碼邏輯混亂在一起。再想想如果再加上錯誤處理的情況,更是酸爽。那么用promise來寫會怎么樣呢?看下邊這樣的代碼

function getData(){
    return new Promise((resolve,reject) =>{
        // ... send request to get data
        
        if(/* get successfully*/){
            resolve(data)
        }else{
            reject(err)
        }
    })
}

function storeData(data){
    return new Promise((resolve,reject)=>{
        // ... store the data
        
        if(/*store successfully*/){
            resolve(data)
        }else{
            reject(err)
        }
    })
}


getData()
    .then(data => storeData(data))
    .then(data => console.log("the process is done",data));
    .catch(err => console.error("there is the err",err));

這樣寫是不是就是很清楚了,先getData,然后再storeData,最后將這次運行的情況log了出來,其中有任何的問題,在catch中都可以Catch出來。代碼的邏輯以同步的方式得到了體現。我們來看看如果是其他語言會怎么寫,下邊是個ruby的語言的例子

def get_data 
    // ...send request
    
    if /*get successfully */
        return data
    else
        raise GetDataError
    end
end


def store_data
    // ...save to db
    
    if /*save successfully */
        return data
    else
        raise StoreDataError
    end
end


/*Main Logic*/
begin
    request_data = get_data
    db_data = store_data request_data
    p "here is the store data #{db_data}"
rescue e
    p "here is some errors #{e}"
end

我們對比兩個例子,可以看到在使用的Promise后讓JavaScript的異步方式的編程模式更將清楚,也更加讓人容易理解。

由于JavaScript的執行環境是單線程的,所以大量采用了異步的方式來進行編程,這使得我們寫起代碼并不十分符合我們一般的習慣。但是Promise的出現讓這種問題能得到一定程度的緩解。

但是異步操作異步操作的好處,比如上邊的那個例子,如果我們想要做的同時并發10個操作,那個在ruby或者其他語言中中就要啟多個線程來進行。但是JavaScript就完全沒有這個問題。只要簡單的loop下就行了。

但是如果我們想要在這10個操作完成后根據返回的狀態做點其他操作該怎么做呢?這時候用Promise.all就是最好的了。

let p = Promise.all([p1, p2, p3]);

Promise.all接受數組作為參數傳入,每個元素都是一個promise對象。只要所有子promise都resolved以后,p才會被resolved。只要有一個被rejected,這個p就會被rejected。但是有一點是這些子promise之間并不會有順序的關系。再來看一個例子:

var guid = 0;
function run() {
  guid++;
  var id = guid;
  return new Promise(resolve => {
    setTimeout(function () {
      console.log(id);
      resolve(id);
    }, (Math.random() * 1.5 | 0) * 1000);
  });
}

var promises = Array.from({ length: 10 }, run);
Promise.all(promises)

OUTPUT:

2
3
5
6
7
8
10
1
4
9

從這次的output可以看到,promise之間并沒有順序執行,實際上是并發的。那么如何讓這些promise是順序執行呢?留個大家自己思考下,下篇文章,我們揭曉。或者可以聯系圖表君,私下告訴你答案哦。
ps,當然也可以用一些第三方的庫和方案,例如(async)來實現順序操作,但是代碼的樂趣不就是做些思維挑戰嗎:)

原創文章,歡迎轉發,但請標明出處。歡迎關注圖表君的公眾號,一起成長。在微信中搜索 “多彩數據” 或者 “Data_Visualization”

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

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

相關文章

  • 大話+圖說:Java字節碼指令——只為讓你懂

    摘要:有點基礎的人一定都知道,命令會將源文件編譯成字節碼文件,即文件,其中就包含了大量的字節碼指令。關于字節碼指令的分類,可以從兩個維度進行一是指令的功能,二是指令操作的數據類型。 前言 隨著Java開發技術不斷被推到新的高度,對于Java程序員來講越來越需要具備對更深入的基礎性技術的理解,比如Java字節碼指令。不然,可能很難深入理解一些時下的新框架、新技術,盲目一味追新也會越來越感乏力。...

    Tonny 評論0 收藏0
  • 理解 Javascript 中的 Promise

    摘要:理解承諾有兩個部分。如果異步操作成功,則通過的創建者調用函數返回預期結果,同樣,如果出現意外錯誤,則通過調用函數傳遞錯誤具體信息。這將與理解對象密切相關。這個函數將創建一個,該將在到秒之間的隨機數秒后執行或。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    paulli3 評論0 收藏0
  • 理解 Javascript 中的 Promise

    摘要:理解承諾有兩個部分。如果異步操作成功,則通過的創建者調用函數返回預期結果,同樣,如果出現意外錯誤,則通過調用函數傳遞錯誤具體信息。這將與理解對象密切相關。這個函數將創建一個,該將在到秒之間的隨機數秒后執行或。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    chaos_G 評論0 收藏0
  • 大話javascript 4期:事件循環(2)

    摘要:只要指定過回調函數,這些事件發生時就會進入任務隊列,等待主線程讀取。三主線程從任務隊列中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為事件循環。 一、任務隊列 同步任務與異步任務的由來 單線程就意味著,所有任務需要排隊,前一個任務結束,才會執行后一個任務。如果前一個任務耗時很長,后一個任務就不得不一直等著。 如果排隊是因為計算量大,CPU忙不過來,倒也算了,但是很多時候C...

    李昌杰 評論0 收藏0
  • ES6的Promise:要優雅,也要浪漫

    摘要:就算改變已經發生了,即使再對對象添加回調函數,也會立即得到這個結果。方法接收個參數,第一個參數是狀態的回調函數,第二個參數可選是狀態的回調函數。簡單來講,就是能把原來的回調寫法分離出來,在異步操作執行完后,用鏈式調用的方式執行回調函數。 在ECMAScript 6標準中,Promise被正式列為規范,Promise,字面意思就是許諾,承諾,嘿,聽著是不是很浪漫的說?我們來探究一下這個浪...

    weizx 評論0 收藏0

發表評論

0條評論

EastWoodYang

|高級講師

TA的文章

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