new Promise

new Promise

(全篇大白話曹傀,你在這里不會(huì)看到別的專有名詞,不會(huì)再有新的疑惑稳摄,一篇把你安排的明明白白藻雪。)

Promise的產(chǎn)生背景

為了讓大家能夠更清晰的了解什么是Promise,在這里我首先需要給大家盡量用通俗易懂的語(yǔ)言介紹下兩個(gè)概念.

1. 瀏覽器處理同步異步機(jī)制

  • 首先瀏覽器是多線程的魁索,但是js是單線程的融撞。
  • 多線程就是有多條生產(chǎn)流水線,任務(wù)可以分派每一條生產(chǎn)線上粗蔚。單線程就是只能按照js代碼的書寫順序從上到下按照順序執(zhí)行.(瀏覽器只分配給了js單線程,就是這么孤獨(dú)弱小無(wú)助尝偎,完全不是親生的有某有。左右都是肉鹏控,瀏覽器其實(shí)也很無(wú)奈致扯,不是不給js分配多線程,只是單線程會(huì)讓Dom操作產(chǎn)生沖突当辐,等一系列的問(wèn)題抖僵,也是實(shí)在某的辦法。)
  • 只有單線程的js,碰到一些非常耗時(shí)的js代碼,比如向后端請(qǐng)求數(shù)據(jù)(比如ajax)缘揪,網(wǎng)速如果進(jìn)入5G++++++時(shí)代耍群,光速一樣义桂,可能不會(huì)有什么影響,就怕重回原始2G,少女已經(jīng)完成了到大嫂的蛻變世吨,請(qǐng)求的數(shù)據(jù)才姍姍來(lái)遲澡刹。數(shù)據(jù)拿到了,然后咱們繼續(xù)按照js代碼書寫順序向下走耘婚,然后又碰到了請(qǐng)求數(shù)據(jù),然后又一個(gè)少女完成了蛻變陆赋,這個(gè)蛻變過(guò)程沐祷,就是你經(jīng)常聽(tīng)到的瀏覽器的阻塞。
  • 瀏覽器看著自己的孩子(js)這么難攒岛,心里也是難受啊赖临,為了避免這種阻塞,瀏覽器就想到了一個(gè)辦法灾锯,每逢碰到這種耗時(shí)操作兢榨,就把這種操作,單獨(dú)的放到一個(gè)內(nèi)存空間中(這個(gè)內(nèi)存空間就是我們常說(shuō)的任務(wù)隊(duì)列顺饮,你要是不常說(shuō)吵聪,自動(dòng)忽略常說(shuō)二字),我們寫的js代碼執(zhí)行完之后兼雄,才會(huì)來(lái)到這個(gè)隊(duì)列里面繼續(xù)執(zhí)行吟逝。

2. 什么是回調(diào)函數(shù)?

  • 回調(diào)函數(shù)就是我們執(zhí)行一些異步操作的時(shí)候赦肋,執(zhí)行完之后块攒,可以根據(jù)拿到執(zhí)行結(jié)果進(jìn)行一系列操作的一個(gè)函數(shù)。比如ajax請(qǐng)求后臺(tái)數(shù)據(jù)佃乘,請(qǐng)求成功進(jìn)行的操作囱井,我們就可以稱之為回調(diào)函數(shù)。
function ajax() {
    var xhr= new xhrRequest();
    //onreadystatechange中的操作就是一個(gè)異步操作
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            document.querySelector(".box").innerHTML = xhr.responseText;
        }
    }
    xhr.open("GET", "url", true);
    xhr.send();
}

設(shè)想下趣避,我們有很多個(gè)ajax請(qǐng)求庞呕,ajax1,ajax2,ajax3...,后面的請(qǐng)求都需要用到前面的請(qǐng)求值,這樣我們不得不把后面的請(qǐng)求寫到前面一個(gè)請(qǐng)求的回調(diào)函數(shù)里鹅巍,如果只是多增加一層請(qǐng)求千扶,可能對(duì)代碼可讀性并沒(méi)有多大的影響,但是如果是很多層骆捧,我愿意拿你一天不吃飯去打賭澎羞,你肯定是不愿意在這樣的代碼上看下去的。

function ajax() {
            var xhr = new xhrRequest();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var xhr2 = new xhrRequest();
                    xhr2.onreadystatechange = function () {
                        var xhr3 = new xhrRequest();
                        xhr3.onreadystatechange = function () {
                            var xhr4 = new xhrRequest();
                            xhr4.onreadystatechange = function () {
                                // ...
                            }
                            xhr4.open("GET", `url.php?name=${xhr3.responseText}`, true);
                            xhr4.send();
                        }
                        xhr3.open("GET", `url.php?name=${xhr2.responseText}`, true);
                        xhr3.send();
                    }
                    xhr2.open("GET", `url.php?name=${xhr.responseText}`, true);
                    xhr2.send();
                }
            }
            xhr.open("GET", "url.php?", true);
            xhr.send();
        }

看了上面的代碼敛苇,舉起你們的雙手妆绞,大聲告訴我顺呕,你們深深的迷失在里面無(wú)可自拔,如果你沒(méi)有迷失括饶,反而很酸爽株茶,找我我在幫你嵌套100層,是男人就酸爽100層图焰。不說(shuō)100層启盛,幾乎沒(méi)有人在嵌套了18層后,還能從里面逃出來(lái)技羔,這就是傳說(shuō)中的回調(diào)地獄僵闯,為了把受苦受難的猿人們從地獄中解救出來(lái).他來(lái)了,他來(lái)了藤滥,他內(nèi)褲外穿走來(lái)了鳖粟,他就是Promise.

Promise的使用

在長(zhǎng)篇大論之前,我先說(shuō)幾點(diǎn)我在痛苦中總結(jié)的精髓拙绊。這個(gè)再網(wǎng)上其他地方基本是看不到的向图。每次看別人的文章,雖然可能很詳細(xì)标沪,但是對(duì)于當(dāng)時(shí)還是非常小白的我來(lái)說(shuō)根本沒(méi)辦法去理解榄攀。

  1. .catch就是.then中處理reject的函數(shù)的另一種寫法,當(dāng)在then中有對(duì)reject拋出的數(shù)據(jù)做一些邏輯處理時(shí)谨娜,.catch是不會(huì)觸發(fā)航攒,當(dāng).then中沒(méi)有對(duì)reject拋出的異常做處理時(shí),才會(huì)觸發(fā).catch趴梢。
  2. .catch寫在一連串.then()之后.then().then().....then().catch()漠畜,無(wú)論哪一個(gè).then里拋出了異常會(huì)觸發(fā).catch。
  3. promise或者.then()中代碼出錯(cuò)或者主動(dòng)reject()都會(huì)導(dǎo)致拋出異常坞靶。
  4. 每一個(gè).then中返回的都是一個(gè)Promise對(duì)象憔狞,這也是為啥可以一直.then的原因。
  5. 只要是異步操作都可以寫在new Promise之中彰阴,在一個(gè)代碼塊之中只能有一個(gè)resolve()||reject(),也就是在這倆出現(xiàn)之后瘾敢,這個(gè)代碼塊之中再次出現(xiàn)都不會(huì)生效,代碼塊就是一個(gè)大括號(hào)包著的東西{ 尿这。簇抵。。}射众。
  6. 差一點(diǎn)忘記一個(gè)很重要的東西碟摆,resolve(res)中的值,就是你異步操作叨橱,獲取到的值典蜕,然后通過(guò)reslove()傳到.then(res=>{console.log(res)})中断盛,這樣就不用一層套一層的處理數(shù)據(jù),從而避免了回調(diào)地獄的產(chǎn)生愉舔。
 function guess大小() {
            let num = parseInt(Math.random() * 6 + 1)
            return new Promise((resolve, reject) => {
                if (num > 3) {
                    console.log('大');
                    resolve('then中的大')
                    console.log('大2');
                } else {
                    console.log('小');
                    reject('then中的小')
                    console.log('小2'); 
                }
                console.log('開(kāi)始啦1');
                setTimeout(() => {
                    resolve(11111)
                    console.log(123);
                }, 000);
                console.log('開(kāi)始啦2');
                setTimeout(() => {
                    console.log(66666666);
                }, 2000);
            }
            )
        }
        guess大小().then(
            //下面這兩個(gè)是es6中函數(shù)的寫法钢猛,詳情參見(jiàn)箭頭函數(shù)
            res=>{
                //當(dāng)為小時(shí),就不會(huì)進(jìn)入這一層轩缤,下面一層.then中的res就位undefined
                console.log(res);
                // return '2222'
                return new Promise((resolve,reject)=>{
                    resolve (33333)
                })
            },
            rej=>{
                console.log(rej);
            }
        ).then(res=>{
            
            console.log(res);  
        })
        依次打印為
        大
        大二
        開(kāi)始啦1
        開(kāi)始啦2
        then中的大
        '333'
        '123'
        '456'
        '66666666'

通過(guò)上面代碼以及打印結(jié)果命迈,你不難發(fā)現(xiàn),resolve,reject無(wú)論寫在哪里典奉,無(wú)論是同步代碼中或者異步代碼中躺翻,都會(huì)在這個(gè)執(zhí)行之后,執(zhí)行then,resolve和reject也是一個(gè)異步操作卫玖,在和這個(gè)異步操作處于同一個(gè)異步或者同步代碼,優(yōu)于.then中的代碼先執(zhí)行.setTimeout就是一個(gè)異步的代碼,無(wú)論延遲時(shí)間是多少踊淳。

第一次接觸某些知識(shí)可能有些繞假瞬,自己一定要?jiǎng)邮謱?shí)踐下。編程不像是讀書迂尝,你看了很多文章脱茉,就會(huì)對(duì)應(yīng)的增加你很多知識(shí)。開(kāi)發(fā)更多的像是健身垄开,你看的健身相關(guān)方面的知識(shí)再多琴许,帶給你最多的可能就是和別人討論的資本,但他真的對(duì)增加你身上的肌肉沒(méi)有多少幫助溉躲。

想成為大牛榜田,沒(méi)有捷徑可言。擼起你的雙手锻梳,你敲的每一行有效代碼箭券,都會(huì)見(jiàn)證你的成長(zhǎng)。

promise除了以上使用疑枯,還有兩個(gè)不常用的使用方式辩块,如果你感覺(jué)上面的還沒(méi)有徹底理解,你完全可以不看荆永,使用場(chǎng)景很少废亭。

  • Promise.all()
  • Promise.race()

Promise.all()的使用

all中文含義'所有的',由此我們不難猜測(cè)具钥,Promise.all()就是同時(shí)執(zhí)行多個(gè)Promise對(duì)象的豆村。

let fighting = (time) => {
    return new Promise((resolve, reject) => {
        console.log(123);
        setTimeout(() => {
            resolve(`敵人還有${time / 1000}秒到達(dá)戰(zhàn)場(chǎng),全軍出擊`)
        }, time)
    })
}
let p1 = fighting(5000)
let p2 = fighting(10000)
//注意觀察all參數(shù)數(shù)組中每一項(xiàng)的順序
Promise.all([p1, p2]).then((result) => {
    console.log(result)       // [ '敵人還有5秒到達(dá)戰(zhàn)場(chǎng)氓拼,全軍出擊', '敵人還有10秒到達(dá)戰(zhàn)場(chǎng)你画,全軍出擊' ]
}).catch((error) => {
    console.log(error)
})
Promise.all([p2, p1]).then((result) => {
    console.log(result)       // [ '敵人還有10秒到達(dá)戰(zhàn)場(chǎng)抵碟,全軍出擊', '敵人還有5秒到達(dá)戰(zhàn)場(chǎng),全軍出擊' ]
}).catch((error) => {
    console.log(error)
})

通過(guò)以上代碼不難發(fā)現(xiàn)坏匪,Promise.all()參數(shù)是一個(gè)數(shù)組拟逮,數(shù)組里的一個(gè)個(gè)的Promise對(duì)象,他們傳遞給then的結(jié)果也是一個(gè)數(shù)組适滓,這個(gè)數(shù)組里的順序是和all中數(shù)組順序一一對(duì)應(yīng)的,只有在這個(gè)數(shù)組中所有的Promise對(duì)象都執(zhí)行完成才會(huì)獲得這個(gè)結(jié)果敦迄。catch中會(huì)得到最先捕獲到的錯(cuò)誤。在開(kāi)發(fā)中凭迹,Promise.all()主要使用在需要多個(gè)異步完成后罚屋,才能進(jìn)行的回調(diào)。

Promise.race()的使用

race中文含義'速度'嗅绸,由此我們依然可以很容易猜到脾猛,Promise.race()也是同時(shí)執(zhí)行多個(gè)Promise對(duì)象的。

let fighting = (time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`敵人還有${time / 1000}秒到達(dá)戰(zhàn)場(chǎng)鱼鸠,全軍出擊`)
        }, time)
    })
}
let p1 = fighting(10000)
let p2 = fighting(5000)
Promise.race([p1, p2]).then((result) => {
    console.log(result)//敵人還有5秒到達(dá)戰(zhàn)場(chǎng)猛拴,全軍出擊
})

Promise.race()中參數(shù)和Promise.all()相同,仍然是一個(gè)數(shù)組蚀狰,數(shù)組里還是一個(gè)一個(gè)的Promise對(duì)象愉昆,不同的是傳遞給then的結(jié)果是這些Promise對(duì)象中最先執(zhí)行完成的那個(gè)所傳遞的,是一個(gè)字符串形式麻蹋。開(kāi)發(fā)中跛溉,幾乎很難碰到Promise.race()的使用場(chǎng)景。

一個(gè)夢(mèng)想開(kāi)飯店卻被迫輾轉(zhuǎn)在前端的榮耀王者渣渣扮授。

說(shuō)在最后的話

千山萬(wàn)水都是情芳室,點(diǎn)點(diǎn)關(guān)注行不行。
萬(wàn)水千山都是愛(ài)糙箍,留個(gè)評(píng)論也不賴渤愁。

全篇都是小編我一個(gè)字一個(gè)字碼出來(lái)的,如果我的文章真的對(duì)你有幫助深夯,還請(qǐng)動(dòng)動(dòng)你發(fā)財(cái)?shù)男∈侄陡瘢ξ以缛臻_(kāi)個(gè)飯店。
賺錢是順便的咕晋,不讓每一個(gè)初入前端的人走我走過(guò)的痛苦是認(rèn)真的雹拄。
本人渣渣,難免不足掌呜,歡迎指正滓玖。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市质蕉,隨后出現(xiàn)的幾起案子势篡,更是在濱河造成了極大的恐慌翩肌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禁悠,死亡現(xiàn)場(chǎng)離奇詭異念祭,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)碍侦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門粱坤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人瓷产,你說(shuō)我怎么就攤上這事站玄。” “怎么了濒旦?”我有些...
    開(kāi)封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵株旷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我尔邓,道長(zhǎng)灾常,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任铃拇,我火速辦了婚禮,結(jié)果婚禮上沈撞,老公的妹妹穿的比我還像新娘慷荔。我一直安慰自己,他們只是感情好缠俺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布显晶。 她就那樣靜靜地躺著,像睡著了一般壹士。 火紅的嫁衣襯著肌膚如雪磷雇。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天躏救,我揣著相機(jī)與錄音唯笙,去河邊找鬼。 笑死盒使,一個(gè)胖子當(dāng)著我的面吹牛崩掘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播少办,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼苞慢,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了英妓?” 一聲冷哼從身側(cè)響起挽放,我...
    開(kāi)封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绍赛,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后辑畦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吗蚌,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年航闺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了褪测。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡潦刃,死狀恐怖侮措,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乖杠,我是刑警寧澤分扎,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站胧洒,受9級(jí)特大地震影響畏吓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卫漫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一菲饼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧列赎,春花似錦宏悦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至诗越,卻和暖如春砖瞧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嚷狞。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工块促, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人感耙。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓褂乍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親即硼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逃片,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354