Promise基本使用(慕課Promise教程筆記)

很久沒寫博客了......看了很多關於Promise的文章,但是感覺也不是很理解,沒辦法去就看視頻了。偶然發現慕課裏有個關於Promise的視頻,然後今天看了前兩章,順便整理了下筆記,記錄下吧~

Promise

是什麼?

  • 用於異步計算。

  • 可以將異步操作隊列化,按照期望的順序執行,返回符合預期的結果。

  • 可以在對象之間傳遞和操作Promise,幫助我們處理隊列。

 

產生的原因

  • JavaScript包含大量的異步操作(AB工作的完成順序,和交付他們時間順序無關)

  • 異步操作的常見語法

    • 事件偵聽和響應

    • 回調

  • 常見異步事件(瀏覽器中的JavaScript)

    • 異步操作以事件爲主

    • 回調主要出現在Ajax和File API

  • Node.js是無阻塞高併發、依賴大量回調函數

 

異步回調的問題

  • 嵌套層次很深,容易陷入回調地獄,使得代碼難以維護。

  • 無法正常使用return和throw。

  • 無法正常檢索堆棧信息。

  • 多個回調之間難以建立聯繫。

ps:

  • 因爲異步回調函數處於新的棧中,在此棧中無法獲取之前的棧的信息,之前的棧也無法獲取此棧中的錯誤,因此try和catch是無法生效的。

  • 因爲無法判斷異步執行順序,只能在外層作用域聲明大量的變量供內層作用域使用,導致這些變量有可能會被其他函數訪問和修改,從而導致錯誤。

 

Promise詳解

創建過程:

  1. 初始化Promise實例。

  2. 在實例中傳入參數,該參數是一個函數(執行器)。

  3. 執行器擁有兩個參數:resolve、reject。

  4. 成功調用resolve方法,失敗調用reject方法。不同的方法執行完會改變Promise實例的狀態。

  5. 執行then方法中對應的函數。

new Promise(
	/* 執行器 executor */
    function(resolve, reject) {
        // 一段耗時很長的異步操作
        
        resolve(); // 數據處理完成
        
        reject(); // 數據處理出錯
    }
)
.then(function A() {
	// 成功,下一步
}, function B() {
	// 失敗,做相應處理
});

理解:

  • Promise是一個代理對象,它和原先要進行的操作並無關係。

  • 它通過引入的一個回調,避免更多的回調。

  • Promise狀態發生改變,就會觸發.then()裏的響應函數處理後續步驟。

  • Promise狀態一經改變,不會再變。

  • Promise實例一經創建,執行器立即執行。

   

 

Promise的三個狀態

  • pending【待定】初始狀態 —— 實例化

  • fulfilled【實現】操作成功 —— 調用resolve

  • rejected【被否決】操作失敗 —— 調用reject

 

簡單範例

定時執行

console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    },2000);
})
    .then( value => {
    console.log(value + ' world');
})
​
//輸出結果
// here we go
/* 
Promise {
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: undefined
}
*/
// 兩秒後
// hello world

執行順序:先輸出‘here we go’,接着執行定時器,兩秒後將‘hello’傳給.then()函數,輸出‘hello, world'

 

兩步執行(常用)

console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
    .then ( value => {
        console.log( value );
        return new Promise( resolve => {
            setTimeout( () => {
                resolve('world');
            }, 2000);
        });
    })
    .then ( value => {
        console.log( value + ' world');
});
​
//輸出結果
// here we go
/* 
Promise {
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: undefined
}
*/
// 兩秒後
// hello 
// 兩秒後
// world world 

執行順序:

先輸出‘here we go',接着進入執行器,兩秒後將'hello’傳給第一個.then()函數;

第一個.then()函數輸出‘hello',返回一個新的Promise;

新的Promise中開始執行器,兩秒後將’world'傳給‘第二個then函數;

第二個.then()函數輸出’world world'。

 

對已完成的Promise執行.then()

console.log('start');
​
let promise = new Promise( resolve => {
    setTimeout( () => {
        console.log('the promise fulfilled');
        resolve('hello, world');
    }, 1000);
});
​
setTimeout( () => {
    promise.then( value => {
        console.log(value);
    })
}, 3000)
​
//輸出結果
// start
/* 
Promise {
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: undefined
}
*/
// the promise fulfilled
// 1秒後
// 兩秒後
// hello, world

執行順序:先輸出‘start’,接着兩個定時器同時執行,一秒後輸出'the promise fulfilled',並將‘hello, world'傳出;再過兩秒,執行.then(),輸出’hello, world'。

promise隊列的重要特性

在任何地方生成了一個promise隊列之後,我們可以把它作爲一個變量進行牀底,如果我們的操作是隊列的狀態,即先進先出的狀態,就可以在後面追加任意多的.then(),不管之前的隊列是完成還是沒有完成,隊列都會按照固定的順序完成。(下個例子更形象)

 

在.then()函數裏面不返回新的Promise(並不影響.then()的執行)

console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
    .then( value => {
        console.log(value);
        console.log('everyone');
        (function() {
            return new Promise( resolve => {
                setTimeout( () => {
                    console.log('Mr.Laurence');
                    resolve('Merry Xmas');
                 }, 2000);
             });
        }());
        return false;
    })
    .then( value => {
        console.log( value + ' world');
})
​
//輸出結果
// here we go
/* 
Promise {
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: undefined
}
*/
// 兩秒後
// hello
// everyone
// false world
// 兩秒後
// Mr.Laurence

執行順序:

輸出‘here we go',進入Promise實例中,兩秒後將’hello‘傳給第一個.then();

第一個.then()輸出’hello',接着輸出‘everyone',接着執行立即執行函數。在此同時第一個.then()返回false,即將false傳給第二個.then();

第二個.then()輸出’false world';(如果註釋掉return false,則輸出'undefined world',可見返回結果不影響Promise繼續往下執行)

在第一個.then()返回false後的兩秒,輸出'Mr.Lanrence'。

 

.then()

  • .then()接受兩個函數作爲參數,分別代表fulfilled和rejected

  • .then()返回一個新的Promise實例,所以它可以鏈式調用

  • 當前面的Promise狀態改變時,.then()根據其最終狀態,選擇特定的狀態響應函數執行

  • 狀態響應函數可以返回新的Promise,或者其他值

  • 如果返回新的Promise,那麼下一級.then()會在新Promise狀態改變之後執行

  • 如果返回的是其他任何值,則會立即執行下一級.then()

console.log('start');
new Promise(resolve => {
    console.log('Step 1');
    setTimeout(() => {
        resolve(100);
    }, 1000);
})
    .then(value => {
        return new Promise(resolve => {
            console.log('Step 1-1');
            setTimeout(() => {
                resolve(110);
            }, 1000);
        })
    })
    .then(value => {
        console.log('Step 1-2');
        return value;
    })
    .then(value => {
        console.log('Step 1-3');
        return value;
    })
    .then(value => {
        console.log(value);
        console.log('Step 2');
})
​
// 輸出
// start
// Step 1
// 一秒後
// Step 1-1
// Step 1-2
// Step 1-3
// 110
// Step 2

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章