用途
用於處理異步操作,避免地獄式回調,比如ajax
請求,處理起來更加簡單方便,代碼看起來也更容易理解,便於維護。
概念
Promise
對象用於表示一個異步操作的最終狀態(完成或失敗),以及其返回的值。 Promise
共有三種狀態,相應狀態會觸發相應的回調函數。
-
pending
: 初始狀態。什麼回調函數也不觸發。-
調用構造函數如
new Promise((resolve, reject) => {})
,在這個exextutor
函數中要麼調用resolve
是狀態改爲完成,要麼調用reject
使狀態改爲失敗,要麼就什麼都不調用,這個時候就是pending
狀態,此時[[PromiseValue]]
爲undefined
。var result = new Promise((resolve, reject) => { })
-
在
.then
或.catch
中返回值爲上面直接使用構造函數的情況,並且在其內部也什麼都不返回,那麼這個時候也是pending
。var result = new Promise((resolve, reject) => { resolve('xxx') }).then((res) => { return new Promise((resolve, reject) => { }) })
-
在
.then
或.catch
中無返回值的時候,這個時候返回的狀態爲前面的Promise
的狀態,如果前面的狀態爲pending
,那麼這裏返回的也是pending
,只不過沒有返回值,返回的Promise
中[[PromiseValue]]
爲undefined
。var result = new Promise((resolve, reject) => { }).then((res) => { })
-
-
fulfilled
: 成功狀態。觸發綁定的‘onfulfilled’
方法。-
在
executor
函數中調用resolve
var result = new Promise((resolve, reject) => { resolve('xxx') })
-
在
.then .catch
中調用Promsie.resolve
var result = new Promise((resolve, reject) => { resolve('xxx') }).then((res) => { return Promise.resolve('bbbb') })
-
在
.then .catch
中的返回值爲一個普通值,值作爲[[PromiseValue]]`的值。var result = new Promise((resolve, reject) => { resolve('xxx') }).then((res) => { return 'xxxx' })
-
在
.then
或.catch
中無返回值的時候,這個時候返回的狀態爲前面的Promise
的狀態,如果前面的狀態爲resolved
,那麼這裏返回的也是resolved
,只不過沒有返回值,返回的Promise
中[[PromiseValue]]
爲undefined
。var result = new Promise((resolve, reject) => { resolve('xxx') }).then((res) => { })
-
-
rejected
: 失敗狀態。觸發綁定的‘onrejected’
方法。-
在
executor
函數中調用rejecte
var result = new Promise((resolve, reject) => { reject('xxx') })
-
在
.then .catch
中調用Promsie.reject
var result = new Promise((resolve, reject) => { resolve('xxx') }).then((res) => { return Promise.reject('bbbb') })
-
在
.then .catch
中拋出一個錯誤時,狀態改爲rejected
,並且觸發onrejected
函數,錯誤信息將作爲作爲拒絕狀態的回調函數的參數值和拒絕狀態的Promise
中[[PromiseValue]]
的值。var result = new Promise((resolve, reject) => { resolve('xxx') }).then((res) => { throw 'xxxx' }).catch((err) => { console.log(err) // xxxx }) console.log(result) // {[[PromiseStatus]]: "rejected", [[PromiseValue]]: "xxxx"}
-
.then
p.then(onFulfilled, onRejected);
當狀態變成成功狀態的時候調用onFulfilled
, 當狀態變成失敗的時候,調用onRejected
。它返回一個Promise
,而它的行爲與then中的回調函數的返回值有關:
- 如果then中的回調函數返回一個值,那麼then返回的Promise將會成爲接受狀態,並且將返回的值作爲接受狀態的回調函數的參數值。
- 如果then中的回調函數拋出一個錯誤,那麼then返回的Promise將會成爲拒絕狀態,並且將拋出的錯誤作爲拒絕狀態的回調函數的參數值。
- 如果then中的回調函數返回一個已經是接受狀態的Promise,那麼then返回的Promise也會成爲接受狀態,並且將那個Promise的接受狀態的回調函數的參數值作爲該被返回的Promise的接受狀態回調函數的參數值。
- 如果then中的回調函數返回一個已經是拒絕狀態的Promise,那麼then返回的Promise也會成爲拒絕狀態,並且將那個Promise的拒絕狀態的回調函數的參數值作爲該被返回的Promise的拒絕狀態回調函數的參數值。
- 如果then中的回調函數返回一個未定狀態(pending)的Promise,那麼then返回Promise的狀態也是未定的,並且它的終態與那個Promise的終態相同;同時,它變爲終態時調用的回調函數參數與那個Promise變爲終態時的回調函數的參數是相同的。
Promise.resolve
參數可以是三種參數類型
- Promise.resolve(value);
- Promise.resolve(promise);
- Promise.resolve(thenable);
如果參數類型是普通的值那麼返回的Promise
狀態仍然是resolve
,值爲返回的值,如果返回值是另外兩種情況,那麼返回的Promise
的狀態由返回值來決定。例如下面的例子返回的是reject
,值爲xxxx
var result = Promise.resolve(new Promise((resolve, reject) => {
reject('xxxx')
}))
Promise.reject
接收一個參數,但是參數不會影響返回的Promise
結果,通過Promise.reject
返回的狀態始終都是reject
。
Promise.all
當我們需要並行執行多個異步的時候,就可以使用這個方法,該方法接收一個可以迭代的對象,例如數組
,數組中一般都是我們需要並行運行的Promise
對象,如果是普通值那麼也會直接返回。只有每一項都爲resolve
時,纔會調用.then
中的成功方法,並且回調參數值一個包含前面所有結果的數組,並且順序也和前面一樣,否則調用失敗的回調。看個例子
var a = 1
var b = new Promise((resolve, reject) => {
setTimeout(function(){
resolve('xxxx')
}, 1000)
})
var c = Promise.resolve('aaa')
var result = Promise.all([a, b, c]).then((values) => {
console.log(values) // 1, xxx, aaa
}).catch((err) => {
console.log(err)
})
對於Promise.all
的同步或者異步,如果值是空的可迭代對象,那麼將是同步的,其他情況均爲異步。