JS執(zhí)行——Promise

Promise

Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理且更強(qiáng)大。它最早由社區(qū)提出并實(shí)現(xiàn),ES6將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn),統(tǒng)一了用法,并原生提供了Promise對(duì)象。

特點(diǎn)

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

用法

創(chuàng)建Promise實(shí)例

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

??Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是resolvereject。它們是兩個(gè)函數(shù),由JavaScript引擎提供,不用自己部署。
??resolve作用是將Promise對(duì)象狀態(tài)由“未完成”變?yōu)椤俺晒Α保簿褪?code>Pending -> Fulfilled,在異步操作成功時(shí)調(diào)用,并將異步操作的結(jié)果作為參數(shù)傳遞出去;而reject函數(shù)則是將Promise對(duì)象狀態(tài)由“未完成”變?yōu)椤笆 保簿褪?code>Pending -> Rejected,在異步操作失敗時(shí)調(diào)用,并將異步操作的結(jié)果作為參數(shù)傳遞出去。

then

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

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

基本用法示例

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

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

執(zhí)行順序

??接下來(lái)我們探究一下它的執(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新建后會(huì)立即執(zhí)行,所以首先輸出 AAA。然后,then方法指定的回調(diào)函數(shù)將在當(dāng)前腳本所有同步任務(wù)執(zhí)行完后才會(huì)執(zhí)行,所以BBB 最后輸出。

與定時(shí)器混用

??首先看一個(gè)實(shí)例:

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的順序不必再說(shuō),而2與3先輸出Promise的then,而后輸出定時(shí)器任務(wù)。原因則是Promise屬于JavaScript引擎內(nèi)部任務(wù),而setTimeout則是瀏覽器API,而引擎內(nèi)部任務(wù)優(yōu)先級(jí)高于瀏覽器API任務(wù),所以有此結(jié)果。

拓展 async/await

async

??顧名思義,異步。async函數(shù)對(duì) Generator 函數(shù)的改進(jìn),async 函數(shù)必定返回 Promise,我們把所有返回 Promise 的函數(shù)都可以認(rèn)為是異步函數(shù)。特點(diǎn)體現(xiàn)在以下四點(diǎn):

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

await

??顧名思義,等待。正常情況下,await命令后面是一個(gè) Promise 對(duì)象,返回該對(duì)象的結(jié)果。如果不是 Promise 對(duì)象,就直接返回對(duì)應(yīng)的值。另一種情況是,await命令后面是一個(gè)thenable對(duì)象(即定義then方法的對(duì)象),那么await會(huì)將其等同于 Promise 對(duì)象。

混合使用

??先看示例:

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,返回一個(gè)Promise。然后在handle函數(shù)前加上async關(guān)鍵詞,這樣就定義了一個(gè)async函數(shù)。在該函數(shù)中,利用await來(lái)等待一個(gè)Promise。

Promise優(yōu)缺點(diǎn)

優(yōu)點(diǎn) 缺點(diǎn)
解決回調(diào) 無(wú)法監(jiān)測(cè)進(jìn)行狀態(tài)
鏈?zhǔn)秸{(diào)用 新建立即執(zhí)行且無(wú)法取消
減少嵌套 內(nèi)部錯(cuò)誤無(wú)法拋出
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 弄懂js異步 講異步之前,我們必須掌握一個(gè)基礎(chǔ)知識(shí)-event-loop。 我們知道JavaScript的一大特點(diǎn)...
    DCbryant閱讀 2,877評(píng)論 0 5
  • Promise 對(duì)象 Promise 的含義 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,827評(píng)論 1 56
  • Promise對(duì)象是一種解決異步問(wèn)題的方法,還有的解決方案是asyns 和 await (es7) 這么是目前的終...
    站在大神的肩膀上看世界閱讀 1,334評(píng)論 0 6
  • 透徹掌握Promise的使用,讀這篇就夠了 Promise的重要性我認(rèn)為我沒(méi)有必要多講,概括起來(lái)說(shuō)就是必須得掌握,...
    穿牛仔褲的蚊子閱讀 2,334評(píng)論 0 16
  • 簡(jiǎn)單介紹下這幾個(gè)的關(guān)系為方便起見(jiàn) 用以下代碼為例簡(jiǎn)單介紹下這幾個(gè)東西的關(guān)系, async 在函數(shù)聲明前使用asyn...
    _我和你一樣閱讀 21,482評(píng)論 1 24

友情鏈接更多精彩內(nèi)容