JS執(zhí)行——Promise

Promise

Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理且更強大蝙茶。它最早由社區(qū)提出并實現(xiàn)扣唱,ES6將其寫進了語言標準,統(tǒng)一了用法唐瀑,并原生提供了Promise對象群凶。

特點

  1. 對象的狀態(tài)不受外界影響 (3種狀態(tài))
    • Pending狀態(tài)(進行中)
    • Fulfilled狀態(tài)(已成功)
    • Rejected狀態(tài)(已失敗)
  2. 一旦狀態(tài)改變就不會再變 (兩種狀態(tài)改變:成功或失斀槿臁)
    • Pending -> Fulfilled
    • Pending -> Rejected

用法

創(chuàng)建Promise實例

var promise = new Promise(function(resolve, reject){
    // ... some code
    
    if (/* 異步操作成功 */) {
        resolve(value);
    } else {
        reject(error);
    }
})

??Promise構(gòu)造函數(shù)接受一個函數(shù)作為參數(shù)座掘,該函數(shù)的兩個參數(shù)分別是resolvereject。它們是兩個函數(shù)柔滔,由JavaScript引擎提供溢陪,不用自己部署。
??resolve作用是將Promise對象狀態(tài)由“未完成”變?yōu)椤俺晒Α本龋簿褪?code>Pending -> Fulfilled形真,在異步操作成功時調(diào)用,并將異步操作的結(jié)果作為參數(shù)傳遞出去超全;而reject函數(shù)則是將Promise對象狀態(tài)由“未完成”變?yōu)椤笆 迸厮簿褪?code>Pending -> Rejected,在異步操作失敗時調(diào)用嘶朱,并將異步操作的結(jié)果作為參數(shù)傳遞出去蛾坯。

then

??Promise實例生成后,可用then方法分別指定兩種狀態(tài)回調(diào)參數(shù)疏遏。then 方法可以接受兩個回調(diào)函數(shù)作為參數(shù):

  1. Promise對象狀態(tài)改為Resolved時調(diào)用 (必選)
  2. Promise對象狀態(tài)改為Rejected時調(diào)用 (可選)

基本用法示例

function sleep(ms) {
    return new Promise(function(resolve, reject) {
        setTimeout(resolve, ms);
    })
}
sleep(500).then( ()=> console.log("finished"));

??這段代碼定義了一個函數(shù)sleep脉课,調(diào)用后,等待了指定參數(shù)(500)毫秒后執(zhí)行then中的函數(shù)财异。值得注意的是倘零,Promise新建后就會立即執(zhí)行。

執(zhí)行順序

??接下來我們探究一下它的執(zhí)行順序戳寸,看以下代碼:

let promise = new Promise(function(resolve, reject){
    console.log("AAA");
    resolve()
});
promise.then(() => console.log("BBB"));
console.log("CCC")

// AAA
// CCC
// BBB

??執(zhí)行后呈驶,我們發(fā)現(xiàn)輸出順序總是 AAA -> CCC -> BBB。表明疫鹊,在Promise新建后會立即執(zhí)行袖瞻,所以首先輸出 AAA。然后拆吆,then方法指定的回調(diào)函數(shù)將在當前腳本所有同步任務執(zhí)行完后才會執(zhí)行聋迎,所以BBB 最后輸出

與定時器混用

??首先看一個實例:

let promise = new Promise(function(resolve, reject){
    console.log("1");
    resolve();
});
setTimeout(()=>console.log("2"), 0);
promise.then(() => console.log("3"));
console.log("4");

// 1
// 4
// 3
// 2

??可以看到锈拨,結(jié)果輸出順序總是:1 -> 4 -> 3 -> 2砌庄。1與4的順序不必再說,而2與3先輸出Promise的then,而后輸出定時器任務娄昆。原因則是Promise屬于JavaScript引擎內(nèi)部任務佩微,而setTimeout則是瀏覽器API,而引擎內(nèi)部任務優(yōu)先級高于瀏覽器API任務萌焰,所以有此結(jié)果哺眯。

拓展 async/await

async

??顧名思義,異步扒俯。async函數(shù)對 Generator 函數(shù)的改進奶卓,async 函數(shù)必定返回 Promise,我們把所有返回 Promise 的函數(shù)都可以認為是異步函數(shù)撼玄。特點體現(xiàn)在以下四點:

  • 內(nèi)置執(zhí)行器
  • 更好的語義
  • 更廣的適用性
  • 返回值是 Promise

await

??顧名思義夺姑,等待。正常情況下掌猛,await命令后面是一個 Promise 對象盏浙,返回該對象的結(jié)果。如果不是 Promise 對象荔茬,就直接返回對應的值废膘。另一種情況是,await命令后面是一個thenable對象(即定義then方法的對象)慕蔚,那么await會將其等同于 Promise 對象丐黄。

混合使用

??先看示例:

function sleep(ms) {
    return new Promise(function(resolve, reject) {
        setTimeout(resolve,ms);
    })
}
async function handle(){
    console.log("AAA")
    await sleep(5000)
    console.log("BBB")
}

handle();

// AAA
// BBB (5000ms后)

??我們定義函數(shù)sleep,返回一個Promise孔飒。然后在handle函數(shù)前加上async關鍵詞灌闺,這樣就定義了一個async函數(shù)。在該函數(shù)中十偶,利用await來等待一個Promise菩鲜。

Promise優(yōu)缺點

優(yōu)點 缺點
解決回調(diào) 無法監(jiān)測進行狀態(tài)
鏈式調(diào)用 新建立即執(zhí)行且無法取消
減少嵌套 內(nèi)部錯誤無法拋出
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末园细,一起剝皮案震驚了整個濱河市惦积,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌猛频,老刑警劉巖狮崩,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鹿寻,居然都是意外死亡睦柴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門毡熏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坦敌,“玉大人,你說我怎么就攤上這事∮剑” “怎么了杜顺?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蘸炸。 經(jīng)常有香客問我躬络,道長,這世上最難降的妖魔是什么搭儒? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任穷当,我火速辦了婚禮,結(jié)果婚禮上淹禾,老公的妹妹穿的比我還像新娘馁菜。我一直安慰自己,他們只是感情好铃岔,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布火邓。 她就那樣靜靜地躺著,像睡著了一般德撬。 火紅的嫁衣襯著肌膚如雪铲咨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天蜓洪,我揣著相機與錄音纤勒,去河邊找鬼。 笑死隆檀,一個胖子當著我的面吹牛摇天,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播恐仑,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼泉坐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了裳仆?” 一聲冷哼從身側(cè)響起腕让,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎歧斟,沒想到半個月后纯丸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡静袖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年觉鼻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片队橙。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡坠陈,死狀恐怖萨惑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仇矾,我是刑警寧澤咒钟,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站若未,受9級特大地震影響朱嘴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粗合,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一萍嬉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧隙疚,春花似錦壤追、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至伶丐,卻和暖如春悼做,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哗魂。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工肛走, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人录别。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓朽色,卻偏偏與公主長得像,于是被迫代替她去往敵國和親组题。 傳聞我的和親對象是個殘疾皇子葫男,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

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

  • 弄懂js異步 講異步之前,我們必須掌握一個基礎知識-event-loop崔列。 我們知道JavaScript的一大特點...
    DCbryant閱讀 2,695評論 0 5
  • Promise 對象 Promise 的含義 Promise 是異步編程的一種解決方案梢褐,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,698評論 1 56
  • Promise對象是一種解決異步問題的方法,還有的解決方案是asyns 和 await (es7) 這么是目前的終...
    站在大神的肩膀上看世界閱讀 1,258評論 0 6
  • 透徹掌握Promise的使用峻呕,讀這篇就夠了 Promise的重要性我認為我沒有必要多講利职,概括起來說就是必須得掌握趣效,...
    穿牛仔褲的蚊子閱讀 2,112評論 0 16
  • 簡單介紹下這幾個的關系為方便起見 用以下代碼為例簡單介紹下這幾個東西的關系瘦癌, async 在函數(shù)聲明前使用asyn...
    _我和你一樣閱讀 21,204評論 1 24