Promise核心基礎
- 2020 年 7 月 30 日
- 筆記
基礎
Promise
- 抽象表達:是js中進行非同步編程的新的解決方案
- 具體解釋:1、從語法上來說是一個構造函數 2、從功能上來說promise對象用來封裝一個非同步操作並可以獲取其結果
- 狀態改變:0、new實例為pending(未知)狀態 1、pending變為resolved(成功) 2、pending變為rejected(失敗)
一個promise對象只能改變一次,成功結果數據一般為value,失敗結果數據一般為reason
示例程式碼
const p1 = new Promise
(
function(resolve, reject) // 這裡的參數為兩個處理函數,該函數稱為執行器函數(執行非同步任務),該函數為同步回調
{
setTimeout
(
function()
{
if(Date.now() % 2 === 0)
{
resolve('成功的數據!');
}
else
{
reject('失敗的數據!');
}
},1000
)
}
)
基本使用
var x;
function fun1()
{
return new Promise
(
function(resolve, reject)
{
// 模擬非同步任務
setTimeout
(
function()
{
console.log('get data successfully'); // 完成數據的接收,並將其處理拋出
resolve('datax');
},2000
)
}
)
}
fun1().then( (value) => { x = value; console.log(x); } ); // 在回調函數內部將數據輸出
// 語法糖
const p1 = Promise.resolve(1); // 構建一個產生一個成功數據為1的promise對象
const p2 = Promise.reject(0); // 構建一個產生一個失敗數據為0的promise對象
p1.then( (value) => { console.log(value); } );
p2.catch( (reason) => { console.log(reason); } );
// Promise.all
const allP = Promise.all([p1, p2]); // 參數為一個包含promise對象的數據
// 對象數組中有一個promise對象返回錯誤就會得到錯誤結果,成功的數據將返回一個數組保存(順序按照對象數組內的順序)
allP.then( value => { console.log('onResolved') } ).catch( reason => { console.log('onRejected', reason) } );
// Promise.race 了解(結果為第一個完成的promise實例對象的結果)
Promise.race([p2, p1]).then( value => { console.log('111') } ).catch( reason => { console.log('000') } );
關鍵問題
- promise實例對象返回的新promise的結果由指定的對應的回調函數的執行結果來決定
- 詳細解釋:
- 如果拋出異常,新的promise狀態為rejected,reason為拋出的異常
- 如果返回值為任意非promise的值,新的promise狀態變為resolved,value的值為返回的值
- 若返回值為一個新的promise,則該promise的結果就會稱為新promise的結果
- 詳細解釋:
程式碼示例
new Promise
(
function(resolve, reject)
{
resolve('正確的輸出結果');
}
).then(value => {console.log('value1', value); return 111;}, reason => {console.log('reason1', reason)}).then(value => {console.log('value2', value)}, reason => {console.log('reason1', reason)});
關鍵問題2
-
成功或者失敗的回調是非同步的
-
執行器函數內部的內容是同步執行(關鍵!)
程式碼示例
new Promise(
function(resolve, reject){
setTimeout(
function(){
resolve('成功返回的數據');
console.log('這是resolve語句後的內容');
}
)
}
).then(value => {console.log(value)}).catch(reason => {console.log(reason)});
異常穿透
示例程式碼
new Promise
(
function(resolve, reject)
{
reject('onRejected');
}
).then
(
value => { console.log('value1', value) },
// reason => { console.log('reason1', reason) } // 若不傳入失敗的回調函數,相當於 reason => {throw reason}
).then
(
value => { console.log('value2', value) },
// reason => { console.log('reason1', reason) }
).then
(
value => { console.log('value3', value) },
// reason => { console.log('reason1', reason) }
).catch
(
reason => { console.log('reason', reason); return new Promise( ()=>{} ); } // 返回一個pending狀態的promise實例對象終止鏈式調用
).then
(
value => { console.log('value4', value) },
reason => { console.log('reason4', reason) }
)
宏隊列與微隊列(補充)
- 宏隊列:dom事件回調、ajax回調、定時器回調
- 微隊列:promise回調、mutation回調
- 注意!:在執行每個宏任務前,都要將微任務執行完
示例程式碼
setTimeout(function(){
console.log('延遲定時器1');
Promise.resolve('promise3').then(value => {console.log(value)});
},0);
setTimeout(function(){
console.log('延遲定時器2');
},0);
Promise.resolve('promise1').then(value => {console.log(value)});
Promise.resolve('promise2').then(value => {console.log(value)});