成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ES6 異步編程之二:Promise

Gilbertat / 2965人閱讀

摘要:今天對于處理異步調(diào)用已經(jīng)有了很多成熟的方案,在我看來這些方案都無外乎在解決一個(gè)問題如何能看似順序地傳遞異步調(diào)用的結(jié)果,本文要說的就是原生提供的一個(gè)解決方案。在對進(jìn)行敘述之前,依舊引用阮大的入門一書中的章節(jié)便于大家更嚴(yán)謹(jǐn)和全面的學(xué)習(xí)和參考。

異步回調(diào)的泥潭

異步回調(diào)是最直接的異步結(jié)果處理模式,將一個(gè)回調(diào)函數(shù)callback扔進(jìn)異步處理函數(shù)中,當(dāng)異步處理獲得結(jié)果之后再調(diào)用這個(gè)回調(diào)函數(shù)就可以繼續(xù)之后的處理,但是如果這個(gè)callback又是一個(gè)異步調(diào)用呢?眾所周知的,在JavaScript中異步回調(diào)的層層嵌套幾乎是反人性的,代碼編寫、修改和閱讀對我等有代碼潔癖的人而言是一種煎熬,這便是異步回調(diào)泥潭了。

今天對于處理異步調(diào)用已經(jīng)有了很多成熟的方案,在我看來這些方案都無外乎在解決一個(gè)問題:“如何能看似順序地傳遞異步調(diào)用的結(jié)果?”,本文要說的Promise就是ES6原生提供的一個(gè)解決方案。

在對Promise進(jìn)行敘述之前,依舊引用阮大的《ECMAScript 6入門》一書中的Promise章節(jié)便于大家更嚴(yán)謹(jǐn)和全面的學(xué)習(xí)和參考。

Promise

承諾,即對未來的許諾,如果諾言實(shí)現(xiàn),然后then)就如何如何……Promise極其生動的講述了一個(gè)言出必行的故事。

    new Promise(function(resolve, reject){
        //開始實(shí)現(xiàn)承諾
        ....
        ....
        if(承諾兌現(xiàn)時(shí)) {
           resolve(dollars);  //兌現(xiàn)承諾的結(jié)果是得到"一大筆美金"
        } else {
           reject("絕交");  //沒兌現(xiàn)承諾就絕交
        }
    }).then(function(dollars){  //然后有錢了,買房買車娶妻生子
       let d1 = buyHouse(dollars); //把每次消費(fèi)剩余的錢傳給下一個(gè)函數(shù)
       let d2 = buyCar(d1);
       let d3 = marry(d2);
       makeBaby(d3);
    }).catch(function(result){//然后如果絕交了,還是繼續(xù)吃土
       //繼續(xù)吃土
    });
    console.log("故事開始....");

看過上面的這個(gè)俗不可耐的故事之后需要理解幾件事情:

言出必行:一個(gè)Promise構(gòu)造出來之后,構(gòu)造時(shí)傳入的異步函數(shù)就立即執(zhí)行;*
注:因大凡使用promise都是在異步調(diào)用場景,下文所說的異步函數(shù)都是指構(gòu)造promise時(shí)傳入的函數(shù)*

Promise實(shí)例內(nèi)部維護(hù)了一個(gè)狀態(tài)機(jī),狀態(tài)變化只可能是pendingresolved或者pendingrejected;

執(zhí)行resolvepending變化到resolved

執(zhí)行rejectpending變化到rejected

拋出錯(cuò)誤:pending變化到rejected

then的第一個(gè)回調(diào)函數(shù)只會在發(fā)生了resolve之后執(zhí)行,本質(zhì)上是在Promise到達(dá)resolved狀態(tài)執(zhí)行;

then的第二個(gè)回調(diào)函數(shù)或者catch的回調(diào)函數(shù)會在發(fā)生reject之后或者異步函數(shù)執(zhí)行拋出錯(cuò)誤時(shí)執(zhí)行,本質(zhì)上是在promise到達(dá)rejected狀態(tài)時(shí)執(zhí)行;

異步函數(shù)執(zhí)行得到結(jié)果可以通過resolve或者reject將結(jié)果傳出;

調(diào)用resolve傳入的值會作為then第一個(gè)回調(diào)函數(shù)的入?yún)?/p>

調(diào)用reject傳入的值作為then第二個(gè)回調(diào)函數(shù)或者catch的回調(diào)函數(shù)的入?yún)?/p>

如果異步函數(shù)拋出了異常,異常會作為then第二個(gè)回調(diào)函數(shù)或者catch的回調(diào)函數(shù)的入?yún)?/p>

"故事開始...."會先輸出,而不是等到then的回調(diào)函數(shù)執(zhí)行完畢才輸出,說明傳入then的回調(diào)函數(shù)是異步執(zhí)行,同理catch也是一樣;

異步函數(shù)調(diào)用鏈

thencatch都是Promise的實(shí)例方法,都返回一個(gè)新的Promise,因此可以輕而易舉地實(shí)現(xiàn)鏈?zhǔn)骄幊?,比如上面的例子中“把每次消費(fèi)剩余的錢”傳給下一個(gè)函數(shù)可以改寫成這樣:

....//前面省略

     .then(function(dollars){  
           return buyHouse(dollars);
        }).then(function(d1){
            return buyCar(d1);
        }).then(function(d2){
            return marry(d2);
        }).then(function(d3){
            return makeBaby(d3);
        }).catch(function(result){
           //繼續(xù)吃土
        });

看到這里你可能認(rèn)為前一個(gè)then回調(diào)函數(shù)的返回值是后一個(gè)then的回調(diào)函數(shù)的入?yún)ⅲ@是不準(zhǔn)確的,因?yàn)楫?dāng)then回調(diào)函數(shù)返回的是個(gè)Promise對象時(shí),這個(gè)Promise對象到終態(tài)時(shí)后一個(gè)then才會執(zhí)行,并且該Promise對象執(zhí)行resolve時(shí)的入?yún)⒉攀呛笠粋€(gè)then的回調(diào)函數(shù)入?yún)ⅲ?/p>

此時(shí)有必要對Promise的一個(gè)類方法resolve做以下說明,它的特性兩句話:

如果傳入的是個(gè)Promise對象,則直接返回這個(gè)Promise

如果是其他任何一個(gè)值(包括Error對象和undefined)則直接轉(zhuǎn)換為一個(gè)resolved狀態(tài)的Promise對象;

比如說下面的代碼:

    //以下的p1和p2邏輯上等同
    let p1 = Promise.resolve(1);
    let p2 = new Promise(function(resolve, reject) {
        resolve(1);
    });
    
    //以下的p3和p4等同
    let p3 = new Promise(function(r, j) {});
    let p4 = Promise.resolve(p3);
    
    console.log(p3 == p4); //true
    console.log(p3 === p4); //true
    
    //以下三者邏輯上等同
    Promise.resolve().then(function(dollars) {
        return 1 + 1;
    }).then(function(v) {
        console.log(v);
    });
    Promise.resolve().then(function(dollars) {
        return new Promise(function(r, j) { r(1 + 1) });
    }).then(function(v) {
        console.log(v);
    });
    Promise.resolve().then(function(dollars) {
        return Promise.resolve(1 + 1);
    }).then(function(v) {
        console.log(v);
    });

我們可以利用Promise異步執(zhí)行結(jié)果傳出的機(jī)制和then的鏈?zhǔn)秸{(diào)用,將層層嵌套的函數(shù)調(diào)用變?yōu)橥ㄟ^then順序連接的鏈?zhǔn)秸{(diào)用
從寫法和形式上看是不是人性很多呢?

通過Promise實(shí)現(xiàn)的鏈?zhǔn)疆惒胶瘮?shù)調(diào)用,以斐波那契數(shù)列舉例如下:

//一個(gè)異步的斐波那契計(jì)算
function fibonacci(v) { 
    return new Promise(function(resolve, reject) {  //每一個(gè)異步調(diào)用都返回了一個(gè)Promise
        setTimeout(function() {
            console.log(`${v.a}`);
            [v.a, v.b] = [v.b, v.a + v.b];
            resolve(v);
        }, 500);
    });
}

//以下兩者邏輯等同,每個(gè)then都等待上一個(gè)promise的結(jié)果形成一條鏈。

// fibonacci({ a: 0, b: 1 })
//     .then(fibonacci)
//     .then(fibonacci)
//     .then(fibonacci)
//     .then(fibonacci)
//     .then(fibonacci)
//     .then(fibonacci);

Promise.resolve()
    .then(() => fibonacci({ a: 0, b: 1 }))
    .then(fibonacci)
    .then(fibonacci)
    .then(fibonacci)
    .then(fibonacci)
    .then(fibonacci)
    .then(fibonacci);

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86780.html

相關(guān)文章

  • ECMAScript 6新特性印象之二:面對對象和模塊化

    摘要:本文參考了以下文章之前的文章新特性印象之一新語法面對對象關(guān)鍵字看上面例子就能明白。定義類的,配合創(chuàng)建新對象。繼承非構(gòu)造器對象的原型是。錯(cuò)誤檢查繼承的目標(biāo)一定要是個(gè)對象或者。的構(gòu)造器是可改寫,但不可枚舉。引入了一個(gè)標(biāo)簽,負(fù)責(zé)載入模塊。 本文參考了以下文章/PPT: Use ECMAScript 6 today Ecmascript 6 Whats next for Javascrip...

    darryrzhong 評論0 收藏0
  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評論0 收藏0
  • JavaScript 異步

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過...

    tuniutech 評論0 收藏0
  • 談?wù)?em>ES6前后的異步編程

    摘要:回調(diào)函數(shù)這是異步編程最基本的方法。對象對象是工作組提出的一種規(guī)范,目的是為異步編程提供統(tǒng)一接口。誕生后,出現(xiàn)了函數(shù),它將異步編程帶入了一個(gè)全新的階段。 更多詳情點(diǎn)擊http://blog.zhangbing.club/Ja... Javascript 語言的執(zhí)行環(huán)境是單線程的,如果沒有異步編程,根本沒法用,非卡死不可。 為了解決這個(gè)問題,Javascript語言將任務(wù)的執(zhí)行模式分成兩種...

    fizz 評論0 收藏0
  • es6 - Promise

    摘要:所謂異步編程中的異步是相對于同步的概念的。是一系列異步編程規(guī)范的統(tǒng)稱。如果中的回調(diào)函數(shù)返回一個(gè)值,那么返回的將會成為接受狀態(tài),并且將返回的值作為接受狀態(tài)的回調(diào)函數(shù)的參數(shù)值。參考介紹基礎(chǔ)篇深入理解與異步編程。 es6 promise與異步編程 對于一些還不具備大量編程經(jīng)驗(yàn)的朋友來說,promise可能是es6比較難以掌握的點(diǎn)。首先是很多名詞,比如Promises,es6 Promise,...

    wemallshop 評論0 收藏0

發(fā)表評論

0條評論

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