溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Promise實(shí)例代碼分析

發(fā)布時(shí)間:2023-03-02 09:42:05 來(lái)源:億速云 閱讀:108 作者:iii 欄目:web開(kāi)發(fā)

這篇文章主要介紹“Promise實(shí)例代碼分析”,在日常操作中,相信很多人在Promise實(shí)例代碼分析問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”P(pán)romise實(shí)例代碼分析”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

先來(lái)看一個(gè)問(wèn)題

我們都知道 JavaScript 是單線程運(yùn)行的,所以如果遇到一個(gè)數(shù)據(jù)需要過(guò)段時(shí)間才能獲取到的情況,就會(huì)形成阻塞導(dǎo)致后面的代碼也無(wú)法執(zhí)行,而這相當(dāng)致命,比如下面代碼

function sum(a, b) {
    const begin = Date.now();
    while(Date.now() - begin < 10000) {

    }
    return a+b;
}

console.log(sum(1,2));
console.log("1");

中間的 while 語(yǔ)句經(jīng)歷了10秒的循環(huán),最終才分別打印出了 3 和 1

然而我們希望的是允許3在10秒后再打印出來(lái),但是1得先打印出來(lái)

這里我們就用到了setTimeout,修改代碼如下

function sum(a, b) {
    setTimeout(() => {
        return a+b;
    },10000)
}

console.log(sum(1,2));
console.log("1");

運(yùn)行一下可以看到1確實(shí)瞬間被打印出來(lái)了,但是本該打印3的位置是undefined

Promise實(shí)例代碼分析

原因在于此時(shí)的console.log同樣沒(méi)有等待setTimeout走完,無(wú)法接收到10秒后的數(shù)據(jù)

所以為了能夠接收到這個(gè)10秒后的數(shù)據(jù),我們可以采用回調(diào)函數(shù)的方式

function sum(a, b, callback) {

    setTimeout(() =>{
        callback(a+b);
    }, 10000)

}

sum(1,2,(result) => {
    console.log(result);
});
console.log("1");

傳入了一個(gè)能夠接收 a+b 為參數(shù)的回調(diào)函數(shù) (result) => {console.log(result);}

所以在10秒后會(huì)執(zhí)行這個(gè)回調(diào)函數(shù),進(jìn)行打印,結(jié)果如下

Promise實(shí)例代碼分析

這樣我們就初步解決了這個(gè)問(wèn)題,一個(gè)需要延時(shí)獲取的數(shù)據(jù)在其他代碼先執(zhí)行后再被獲取。

然而 Promise 還沒(méi)出現(xiàn),這就涉及了另一個(gè)需要改進(jìn)的地方

回調(diào)地獄

這是個(gè)乍一聽(tīng)很唬人的稱呼,實(shí)際上就是多層回調(diào)函數(shù)的嵌套導(dǎo)致的不利于閱讀和調(diào)試的情況。

比如此時(shí)我們想要多次調(diào)用這個(gè)sum函數(shù),要在得到1+2的結(jié)果后,再獲得 1+2+3,1+2+3+4 這些結(jié)果

所以我們得在sum傳入的回調(diào)函數(shù)里再多次調(diào)用sum進(jìn)行嵌套,如下

sum(1,2,(result) => {
    sum(result, 3, (result) => {
        sum(result, 4, (result) => {
            console.log(result);
        })
    })
});

Promise實(shí)例代碼分析

這種類似金字塔的結(jié)構(gòu)可讀性差且不好調(diào)試,被稱作回調(diào)地獄。

所以此時(shí)終于到了Promise出場(chǎng)的時(shí)候,它的出現(xiàn)解決了回調(diào)地獄的問(wèn)題。

Promise 是什么

在使用Promise解決回調(diào)地獄的問(wèn)題前,先來(lái)大致地了解一下什么是Promise。

目前我對(duì)它的判斷是,Promise 是一個(gè)用于存取異步數(shù)據(jù)的對(duì)象。

首先來(lái)看一下空的 Promise 打印出來(lái)會(huì)是什么

const promise = new Promise(()=>{});

Promise實(shí)例代碼分析

其中最關(guān)鍵的就是 PromiseState 和 PromiseResult 兩個(gè)值,之后會(huì)詳細(xì)展開(kāi),這里只要知道Promise中有著這兩個(gè)屬性即可。

接著來(lái)看一下 promise 存數(shù)據(jù)的過(guò)程,最關(guān)鍵的就是要知道有 resolve 和 reject,比如下面代碼

const promise = new Promise((resolve, reject) => {
    const flag = true;
    if (flag) {
        resolve("resolve datas");
    } else {
        reject("reject data");
    }
})

此時(shí)flag為true,所以執(zhí)行的是resolve的存儲(chǔ),得到的結(jié)果如下

Promise實(shí)例代碼分析

而當(dāng)我們把flag改為false,執(zhí)行reject的存儲(chǔ)時(shí),得到的結(jié)果如下

Promise實(shí)例代碼分析

現(xiàn)在是解釋上面兩個(gè)屬性的時(shí)候了,

  • 當(dāng) promise 沒(méi)有存儲(chǔ)數(shù)據(jù)時(shí),PromiseState 的值為 pending,PromiseResult的值為 undefined

  • 當(dāng) promise 使用 resolve 存儲(chǔ)數(shù)據(jù)時(shí),PromiseState 的值為 pending,PromiseResult的值為 相應(yīng)存儲(chǔ)值

  • 當(dāng) promise 使用 reject 存儲(chǔ)數(shù)據(jù)時(shí),PromiseState 的值為 rejected,PromiseResult的值為相應(yīng)存儲(chǔ)值

既然存有兩種類型,讀自然也要分兩種

當(dāng)我們讀取promise中的數(shù)據(jù)時(shí),我們需要使用如下的結(jié)構(gòu)

promise.then(result => {
    console.log(result);
}, reason => {
    console.log(reason);
})

如果數(shù)據(jù)存在resolve中,result會(huì)返回結(jié)果,如果存在reject中,reason會(huì)返回結(jié)果。

使用Promise解決回調(diào)地獄

在初步了解了Promise后,會(huì)發(fā)現(xiàn)目前Promise能做的事,使用回調(diào)函數(shù)也能完成。

所以最主要的還是Promise解決了回調(diào)地獄,比如之前的問(wèn)題,可以寫(xiě)成這種形式

function sum(a, b) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a+b);
        }, 1000);
    })
}

sum(1,2)
    .then(result => sum(result,3))
    .then(result => sum(result,4))
    .then(result => {
        console.log(result);
    })

promise 通過(guò)then方法進(jìn)行讀取后,是個(gè)新的Promise對(duì)象,比如我們可以打印一下

function sum(a, b) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a+b);
        }, 1000);
    })
}

console.log(sum(1,2)
    .then(result => sum(result,3)))

Promise實(shí)例代碼分析

所以這也就給了我們能多次調(diào)用then方法的基礎(chǔ)。

而這也就解決了回調(diào)地獄的問(wèn)題。

到此,關(guān)于“Promise實(shí)例代碼分析”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI