Promise筆記

參考:阮一峯es6(http://es6.ruanyifeng.com/#docs/promise)javascript

時間:2018-07-03java

類型:我的筆記es6

解決的問題:異步編程的一種解決方案。編程

定義:Promise是一個保存着將來纔會執行的事件的容器,建立後就會執行,但它有resolve和reject,做爲將來會執行的事件,等Promise實例執行纔會調用。json

形式數組

 1 //定義一個Promise實例
 2 const promise=new Promise(function(resolve,reject){
 3    console.log('我是Promise內同步的');
 4    setTimeout(function(){
 5        console.log('我是定時器')
 6    },1) 
 7     resolve();
 8 })
 9 //執行promise
10 promise.then(function(){
11     console.log('我是resolve')
12 });
13 console.log('我是同步的2')

分析:Promise建立,內部的同步會當即執行,因此輸出:promise

我是Promise內同步的」  「我是同步的2」異步

而後執行異步:一個定時器和promise實例的resolve,定時器自己就是在同步執行完才執行的,promise.then執行後定時器開始執行;異步編程

接着會輸出:「我是resolve」 「我是定時器」函數

寫到這裏其實和異步沒有任何關係,因此來個異步請求開開眼

 1 //Promise幹倒Ajax
 2 const getJSON=function(url){
 3     const anyName=new Promise(function(resolve,reject){
 4         const xhr=new XMLHttpRequest();
 5         xhr.open('GET',url);
 6         xhr.onreadystatechange=handler;
 7         xhr.send();
 8         const handler = function() {
 9             if(xhr.readyState!==4){
10                 return;
11            }
12             if (xhr.status ===200) {
13                 resolve(xhr.response)
14             }else{
15                   reject(new Error(xhr.statusText))
16             }
17         }
18     })
19     return anyName;
20 }
21 getJSON('我是路徑url').then(function(json){
22     console.log(json+'是Promise實例anyName執行成功resolve傳過來的')      
23 },function(error){
24     console.error('出錯了',error)
25 })

胡亂分析:上述代碼的目的是用Promise封裝一個Ajax,爲撒呢,假若有時候咱們須要某一段代碼的執行是在異步以後返回結果執行,這樣寫就不用把代碼寫在success或者失敗裏,把成功或者失敗分別封裝在resolve或者reject,then裏的函數就是指這兩個。

特色

1.Promise有三種狀態:pending(在進行)resolve(成功)reject(失敗)

2.狀態一旦改變,就不會在變。除非你修改代碼,刷新從新加載。(我很認真)

簡記:(簡單記憶)

  

const anyNamePromise = new Promise(function(resolve,reject){
    ***我是異步代碼***;
    //判斷異步返回狀態
    if (status ===200 ){
        //成功了唄,保存成功以後要執行的函數
        resolve('我是要傳的參數')
    }else{
        //失敗了唄,保存失敗要執行的函數
        reject('沒啥,哥告訴你咋錯的')
    }
})
//告訴你怎麼調用resolve和reject,否則不是乾瞪眼(不是打牌那個,不要打牌,娛樂也不要)
anyNamePromise.then(function('resolve傳過來的'){
    //少俠能夠在這裏寫成功後的要執行的
},function('我也是傳過來的'){
    //不得不說你猜對了,這裏是失敗後要執行的
})
//騷等,會不會以爲這樣寫不太好看,再來一種寫法,這個比較經常使用
anyNamePromise.then(function(){}).catch(function(error){})
//Promise東西好多啊,繼續寫,emmm

擴展

1.resolve的參數除了正常點的值外還能夠是另外一個Promise實例:

const p1=new Promise(function(resolve,reject){
     setTimeout(()=>{reject(new Error('fail'))},2)
})
const p2=new Promise(function(resolve,reject){
    setTimeout(()=>{resolve(p1)},2)
})
p2.then(function(){}).catch(function(){})

解析:p1的狀態決定p2的狀態;p2會等着p1狀態變爲成功或者失敗再決定本身的狀態;

2.then

then返回的是一個新的promise實例,then後還能夠.then,前一個then return回的值能夠被當前的then做爲參數傳遞使用,前一個then的狀態變化,決定後續執行成功仍是失敗的then

1 getJSON('url')
2     .then(()=>{getJSON('newURl')})
3     .then(()=>{},()=>{})

3.catch

處理錯誤

p.then(()=>{})
    .catch(()=>{});
等價於
p.then(()=>{},()=>{})

優先使用catch,由於catch也會把then執行的錯誤也捕獲,catch後.catch會把前一個catch的錯誤捕捉;和try catch不一樣,Promise對象拋出的錯誤不會傳遞到外部,即不會有任何反應

1 function getFn(){
2     return new Promise((resolve,reject)=>{
3         resolve(x+3)
4     })
5 }
6 getFn().then(()=>{console.log('haha')});
7 setTimeOut(()=>{console.log('jh')},4)

解析:Promise內部雖然沒有聲明x會報錯,但並不影響後面定時器的執行,錯誤被Promise吃了

建議:Promise後跟着catch方法,處理Promise內部的錯誤。catch方法返回的仍是個Promise對象,也能夠接着調用then。

4.finally

2018引入的

promise
    .then(()=>{})
    .catch(()=>{})
    .finally(()=>{})

finally最後都會被執行,不接受任何參數;

5.all

const p = Promise.all([p1,p2,p3])

解析:p1,p2,p3是Promise實例,p的狀態僅當p1,p2,p3都爲resolve才resolve,此時p1,p2,p3的值會組成數組返回給p;

         只要有一個rejected,p就會變成rejected,此時第一個被rejected的值傳回給p

const promises=[2,3,4].map(function(val){
   return getJSON('url'+val) 
})
Promise.all(promises)
    .then(posts=>{console.log(posts)})
    .catch((err)=>{console.log(err)})

 若p1,p2,p3有catch,則返回均爲resolve,由於若rejected則會被catch捕獲,返回一個新的promise實例,狀態resolved。

6.race

 1 const p=Promise.race([p1,p2,p3])
 2 //例子
 3 const p=Promise.race([
 4     fetch('隨意實例'),
 5     new Promise((resolve,reject){
 6         setTimeout(()=>{reject(new Error('hello'))},10)
 7     })
 8 ]);
 9 p
10     .then(console.log('hoi'))
11     .catch(console.error);

競賽執行

9.應用

加載圖片

const preImgLoad=function(url){
    const promise = new Promise((resolve,reject)=>{
        let img = new Image();
        img.src=url;
        img.onload=resolve;
        img.onerror=reject;
    })  
}

  總結:promise裏包含着一個異步執行的結果,成功或者失敗,成功resolve和失敗reject兩個函數對應異步結果。通常.then後.catch捕獲錯誤,Promise能夠把錯誤吃了。race和all是多個Promise實例執行,race是競賽,誰先執行完返回誰,all是返回最後結果,若都resolve,則返回結果放在數組裏傳給all,catch後返回的是一個新的Promise實例,其狀態由catch自己決定。finally不管怎樣都會執行的。

相關文章
相關標籤/搜索