Promise羡疗、Generator 函數(shù)與 async/await

前言

本次分享的內(nèi)容是 Promise、Generator 函數(shù)與 async/await 别洪,都是與異步操作相關(guān)的內(nèi)容叨恨,我們常見的異步操作基本是:回調(diào)函數(shù)事件監(jiān)聽,AJAX就是事件監(jiān)聽的一種挖垛,本次分享中也主要以AJAX為例痒钝。

var request = new XMLHttpRequest();

request.onreadystatechange = function () {
    if (request.readyState === 4) {
        if (request.status === 200) {
            return success(request.responseText);
        } else {
            return fail(request.status);
        }
    }
}

request.open('GET', '/api/categories');
request.send();

Promise

首先先看一下Promise是什么:

Promise.png

可以看到Promise是一個構(gòu)造函數(shù),里面有我們熟悉的all痢毒、 reject 送矩、resolve 方法,原型上有 then哪替、catch 方法栋荸,我們可以新建一個Promise 對象來使用。

new Promise(
    /* executor */
    function(resolve, reject) {...}
);

我覺得文檔上說的比我清楚的多:

Promise對象是一個代理對象(代理一個值)凭舶。它允許你為異步操作的成功和失敗分別綁定相應(yīng)的處理方法(handlers )蒸其。 這讓異步方法可以像同步方法那樣返回值,但并不是立即返回最終執(zhí)行結(jié)果库快,而是一個能代表未來出現(xiàn)的結(jié)果的promise對象
一個 Promise有以下幾種狀態(tài):

  • pending: 初始狀態(tài)摸袁,不是成功或失敗狀態(tài)。
  • fulfilled: 意味著操作成功完成义屏。
  • rejected: 意味著操作失敗靠汁。
    pending 狀態(tài)的 Promise 對象可能觸發(fā)fulfilled 狀態(tài)并傳遞一個值給相應(yīng)的狀態(tài)處理方法,也可能觸發(fā)失敗狀態(tài)(rejected)并傳遞失敗信息闽铐。當(dāng)其中任一種情況出現(xiàn)時蝶怔,Promise 對象的 then 方法綁定的處理方法(handlers )就會被調(diào)用(then方法包含兩個參數(shù):onfulfilled 和 onrejected,它們都是 Function 類型兄墅。當(dāng)Promise狀態(tài)為fulfilled時踢星,調(diào)用 then 的 onfulfilled 方法,當(dāng)Promise狀態(tài)為rejected時隙咸,調(diào)用 then 的 onrejected 方法沐悦, 所以在異步操作的完成和綁定處理方法之間不存在競爭)成洗。
    因為 Promise.prototype.then 和 Promise.prototype.catch
    方法返回promise 對象, 所以它們可以被鏈?zhǔn)秸{(diào)用藏否。
promises.png
疑問

既然 .then() 既有reject 也有 resolve的回調(diào)瓶殃,那為什么還有.catch()?

我看網(wǎng)上的說法是說 如果是 .then() 中報錯,則會進入 .catch() 中處理副签,這樣可以避免報錯遥椿,類似于 try catch。

基本api
  • Promise.resolve()
  • Promise.reject()
  • Promise.prototype.then()
  • Promise.prototype.catch()
  • Promise.all() // 所有的完成
  • Promise.race() // 競速淆储,完成一個即可

應(yīng)用

然后我們用Promise來重寫一下ajax:

function ajax (method, url, data) {
    var request = new XMLHttpRequest();
    return new Promise(function (resolve, reject) {
        request.onreadystatechange = function () {
            if (request.readyState === 4) {
                if (request.status === 200) {
                    resolve(request.responseText);
                } else {
                    reject(request.status);
                }
            }
        };
        request.open(method, url);
        request.send(data);
    });
}

var p = ajax('GET', '/api/xxxx');
p.then(function (text) {
    console.log(text);
}).catch(function (status) {
    console.log('ERROR: ' + status);
});

看起來好像并沒有什么改變冠场,但是如果我們想一個請求完成再發(fā)起另一個請求呢?

ajax ('GET',  '/api/hhh').then(function(data) {
  return ajax('POST', '/api/hhhh', data.body);
})

.then(function(data) {
  return ajax('POST', '/api/hhhhh', data.body);
})

.then(function() {
   console.log(data);
});

肯定比無限回調(diào)好看多了本砰。

除此之外碴裙,我們可以使用 Promise.all() 來并行執(zhí)行異步操作。

function func(num){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve(num);
        }, 1000);
    });
    return p; 
}

Promise.all([func(1), func(2), func(3)])
.then(function(results){
    console.log(results);
});

// console的值為 [1, 2, 3]

三個異步操作的并行執(zhí)行的灌具,等到它們都執(zhí)行完后才會進到then里面,all會把所有異步操作的結(jié)果放進一個數(shù)組中傳給then譬巫,就是上面的results咖楣。

Generator 函數(shù)

之前沒怎么接觸過,是一個可以返回多次的函數(shù)芦昔。
generator 函數(shù)由 function*定義诱贿,除了 return 還可以使用 yield 返回多次。那到底怎么用咕缎?

應(yīng)用

先來個簡單的例子:
斐波那契數(shù)列珠十,一般我們要這樣寫:

function fib(max) {
    var
        t,
        a = 0,
        b = 1,
        arr = [0, 1];
    while (arr.length < max) {
        t = a + b;
        a = b;
        b = t;
        arr.push(t);
    }
    return arr;
}
fib(5); // [0, 1, 1, 2, 3]

使用 generator:

function* fib(max) {
    var
        t,
        a = 0,
        b = 1,
        n = 1;
    while (n < max) {
        yield a;
        t = a + b;
        a = b;
        b = t;
        n ++;
    }
    return a;
}

var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: true}

//

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市凭豪,隨后出現(xiàn)的幾起案子焙蹭,更是在濱河造成了極大的恐慌,老刑警劉巖嫂伞,帶你破解...
    沈念sama閱讀 211,496評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孔厉,死亡現(xiàn)場離奇詭異,居然都是意外死亡帖努,警方通過查閱死者的電腦和手機撰豺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,187評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拼余,“玉大人污桦,你說我怎么就攤上這事〕准啵” “怎么了凡橱?”我有些...
    開封第一講書人閱讀 157,091評論 0 348
  • 文/不壞的土叔 我叫張陵小作,是天一觀的道長。 經(jīng)常有香客問我梭纹,道長躲惰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,458評論 1 283
  • 正文 為了忘掉前任变抽,我火速辦了婚禮础拨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绍载。我一直安慰自己诡宗,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,542評論 6 385
  • 文/花漫 我一把揭開白布击儡。 她就那樣靜靜地躺著塔沃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪阳谍。 梳的紋絲不亂的頭發(fā)上蛀柴,一...
    開封第一講書人閱讀 49,802評論 1 290
  • 那天,我揣著相機與錄音矫夯,去河邊找鬼鸽疾。 笑死,一個胖子當(dāng)著我的面吹牛训貌,可吹牛的內(nèi)容都是我干的制肮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,945評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了穿香?” 一聲冷哼從身側(cè)響起坷剧,我...
    開封第一講書人閱讀 37,709評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,158評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡约素,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,502評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了笆凌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圣猎。...
    茶點故事閱讀 38,637評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖乞而,靈堂內(nèi)的尸體忽然破棺而出送悔,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,300評論 4 329
  • 正文 年R本政府宣布欠啤,位于F島的核電站荚藻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏洁段。R本人自食惡果不足惜应狱,卻給世界環(huán)境...
    茶點故事閱讀 39,911評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望祠丝。 院中可真熱鬧疾呻,春花似錦、人聲如沸写半。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,744評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叠蝇。三九已至璃岳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悔捶,已是汗流浹背铃慷。 一陣腳步聲響...
    開封第一講書人閱讀 31,982評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蜕该,地道東北人犁柜。 一個月前我還...
    沈念sama閱讀 46,344評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像蛇损,于是被迫代替她去往敵國和親赁温。 傳聞我的和親對象是個殘疾皇子坛怪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,500評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Promiese 簡單說就是一個容器淤齐,里面保存著某個未來才會結(jié)束的事件(通常是一個異步操作)的結(jié)果,語法上說袜匿,Pr...
    雨飛飛雨閱讀 3,352評論 0 19
  • Promise的含義: ??Promise是異步編程的一種解決方案更啄,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和...
    呼呼哥閱讀 2,167評論 0 16
  • //本文內(nèi)容起初摘抄于 阮一峰 作者的譯文,用于記錄和學(xué)習(xí)居灯,建議觀者移步于原文 概念: 所謂的Promise祭务,...
    曾經(jīng)過往閱讀 1,231評論 0 7
  • 簡單介紹下這幾個的關(guān)系為方便起見 用以下代碼為例簡單介紹下這幾個東西的關(guān)系, async 在函數(shù)聲明前使用asyn...
    _我和你一樣閱讀 21,216評論 1 24
  • 上高三的時候,一直聽我們班主任嘮叨岩灭,再堅持一年拌倍,你們就解放了。然而所謂的解放是什么呢?是不用寫作業(yè)柱恤,還是不用上課了...
    噠噠222閱讀 330評論 0 0