<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>es6</div>
<script type="text/javascript">
// what是Promise:Promise是ES6中提供的一個異步程式設計的解決方案,Promise本身是一個構造函數 typeof Promise // function
// Promise對象代表一個異步操作,有三種狀态:pending(進行中)、fulfilled(已成功)和rejected(已失敗)
// 異步操作成功,Promise對象傳回一個值,狀态變為resolved
// 異步操作失敗,Promise對象抛出一個錯誤,狀态變為rejected
/*
一旦Promise狀态改變,就不會再有變化,任何時候都可以得到這個結果。Promise對象的狀态改變,隻有兩種可能:從pending變為fulfilled 或者 從pending變為rejected。
隻要這兩種情況發生,狀态就不會再變了,會一直保持這個結果,這時就稱為 resolved(已定型)。
如果改變已經發生了,你再對Promise對象添加回調函數,也會立即得到這個結果。這與事件(Event)不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的;
Promise優點:
在處理異步程式時,将異步操作隊列化,按照期望的順序執行,傳回符合預期的結果,這樣即使是多重異步操作,也可以友善的使用Promise進行鍊式調用
Promise缺點:
1、無法取消Promise,一旦建立它就會立即執行,無法中途取消。
2、如果不設定回調函數,Promise内部抛出的錯誤,不會反應到外部。
3、當處于pending狀态時,無法得知目前進展到哪一個階段(剛剛開始還是即将完成)
*/
// 基本使用
const promise = new Promise(function(resolve, reject) {
console.log('Promise++++++++111111');
// 執行一個異步操作
setTimeout(() => {
console.log('Promise+setTimeout:最後輸出')
}, 3000)
resolve('成功'); // 狀态由等待變為成功,傳的參數作為then函數中成功函數的實參
// reject('失敗'); // 狀态由等待變為失敗,傳的參數作為then函數中失敗函數的實參
console.log('Promise++++++++222222');
})
// then中有2個參數,第一個參數是狀态變為成功後應該執行的回調函數,第二個參數是狀态變為失敗後應該執行的回調函數。
promise.then(res => {
console.log('Promise++++++++444444');
console.log('結果1:' + res) // 結果1:成功(如果是reject('失敗')則列印結果是:失敗)
}, err => {
console.log('錯誤1:' + err)
}).then(res => {
console.log('結果2:' + res) // 結果2:undefined
}, err => {
console.log('錯誤2:' + err)
}).finally(() => {
console.log('結束') // finally方法,finally方法用于指定不管 Promise 對象最後狀态如何,都會執行的操作
})
console.log('333333');
/*總結:上述依次列印
Promise++++++++111111
Promise++++++++222222
333333
Promise++++++++444444
結果1:成功
結果2:undefined
結束
Promise+setTimeout:最後輸出
*/
/*==========================Promise.all()方法=================================*/
// 多個 Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(function() {
console.log('p1')
resolve('p1')
}, 3000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(function() {
console.log('p2')
resolve('p2')
}, 5000)
})
// 多個異步操作
Promise.all([p1, p2]).then((res) => {
console.log('成功:' + res) // 成功:p1,p2
})
/*==========================Promise.race()方法=================================*/
// race的用法, 文法和all()一樣,但是傳回值有所不同,race根據傳入的多個Promise執行個體,隻要有一個執行個體resolve或者reject,就隻傳回該結果,其他執行個體不再執行,
// 也就是說多個異步程式,隻傳回響應最快的那個異步程式,不論成功或者失敗,就把最快響應的傳回值傳回,後面的異步程式不再執行
const p4 = new Promise((resolve, reject) => {
setTimeout(function() {
console.log('p4')
resolve('p4')
}, 9000)
})
const p5 = new Promise((resolve, reject) => {
setTimeout(function() {
console.log('p5')
reject('p5')
}, 6000)
})
Promise.race([p4, p5]).then().catch(res => {
console.log('失敗:' + res) // p5 失敗:p5 p4
})
/*==========================Promise.resolve()方法=================================*/
// Promise的resolve方法,用于将非Promise類型的對象,轉為Promise對象,這樣就可以調用Promise原型對象上的方法了
// 沒有參數,如果沒有參數,這直接傳回一個resolved狀态的Promise對象
const p7 = Promise.resolve()
// 相當于
const p8 = new Promise(resolve => {
resolve(undefined)
})
p7.then(res => {
console.log('p7-resolve()沒有參數時候等價與:' + res) // 輸出 undefined
})
// 參數是一個不具有then方法的對象,或者是一個基數資料類型的值,則Promise.resolve方法傳回一個新的 Promise 對象,狀态為resolved,值為指定值
const p9 = Promise.resolve('123')
p9.then(res => {
console.log('p9-resolve()有參數時候等價與:' + res) // 輸出 '123'
})
// 參數是一個具有then方法的對象,Promise.resolve方法會将這個對象轉為 Promise 對象,然後就立即執行thenable對象的then方法
const obj = {
then: function(resolve, reject) {
resolve(100)
}
}
const p10 = Promise.resolve(obj)
p10.then(res => {
console.log(res) // 100
})
// 特别的:參數是一個Promise對象,那麼将原封不動的傳回這個Promise對象
// reject與resolve方法基本類似,但是要注意一種情況,就是當參數是一個thenable對象時
const thenable = {
then(resolve, reject) {
reject('出錯了');
}
};
Promise.reject(thenable)
.catch(e => {
console.log(e === thenable) // true
})
</script>
</body>
</html>