Promise/async/await 研究筆記

dint發表於2024-11-15

Promise/async/await 是ES6裡面的新特性 個人理解如下:

1.建立Promise物件後會立即執行內部函式fn new Promise(fn);

1 new Promise(function(resolve, reject){
2          console('new 完後馬上執行這個函式哦');
3      });

2. Promise 可以透過resolve(r)返回結果 ,then函式接收結果 ,catch函式捕獲 throw e 異常, reject(e) 手動觸發catch呼叫

 1 function test1(){
 2         return new Promise(function(resolve, reject){
 3            window.setTimeout(function(){
 4               try{
 5                 //throw '丟擲的異常222'; //這裡丟擲的異常外部promise不能 直接  catch 到哦 需內部自己捕獲後呼叫 reject 傳遞到catch
 6                 
 7                 console.log('test1.....');
 8                 resolve('ooookkkk..'); //resolve 向下一個then傳遞結果
 9               
10               
11               }catch(e){
12                  reject(e); //向catch 傳遞結果
13               }
14               
15            },1000);
16            //throw '丟擲的異常111'; //這裡丟擲的異常能直接被.catch() 捕獲到哦  但是會使 setTimeout 裡面的 resolve不再呼叫了哦
17         }).then(function(r){
18             console.log('呼叫 resolve 後會執行我哦');
19             console.log(r);
20         
21         }).catch(function(r){
22             console.log('呼叫 reject 或throw e後 後會執行我哦');
23             console.log(r);
24         });
25      }
26      
27     //let res1= test1(); // res1 是 Promise;
28     //console.log(res1);

3.async 關鍵字修飾函式後 函式的返回值就是Promise物件 如果函式就return a ; 那麼Promise物件的result=a;

 1 async function test3_(n){ //async return 會封裝成 Promise 並把返回值 作為promise的result屬性內容\
 2         
 3         window.setTimeout(function(){
 4               console.log(n);
 5               return n+100;
 6            },1000);
 7            if (n===3){
 8               throw '異常123';
 9            }
10            let a='返回string='+n;
11            return a;  //實際返回Promise(result=a);
12      }
13      
14      async function test3(){
15         let a= await test3_(1);  //這裡的返回值是 函式的實際return 返回值 並不會等待裡面的setTimeout完成
16         console.log(a);
17         let b=     test3_(2); //這裡是 Promise 封裝 裡面封裝了 return 返回值 作為result欄位
18         console.log(b);
19         let c=      test3_(3).catch(function(r){console.log(r);});
20         console.log(c);
21         
22         let d=new Promise(function(a,b){
23            console.log('這樣也可以直接執行哦');
24            return 'oookkkk'; //這裡的返回意義不大
25         }).then(function(r){
26            console.log('成功了會執行我哦');
27         });
28         
29         console.log(d);
30      }
31      //test3();

4.await 必須在async修飾的函式中使用

1 function test6(){
2         
3       }
4       function test7(){
5          let z=await test6();//這種寫法是錯誤的  因為test6沒有返回Promise物件
6       }

5. await fn(); 中 fn 如果返回值不是Promise 物件, 則和普通函式呼叫無異

 1 function test5(){
 2          
 3          console.log('111111');
 4          window.setTimeout(function(){
 5             console.log('222222');
 6          },1000);
 7          return 33333;
 8       }
 9       async function test5_(){
10           let a=await test5(); //這個時候和普通呼叫無異 因為沒有返回Promise物件
11           console.log(a);
12       }
13       test5_();

6. await fn(); 中 fn 如果返回Promise 物件 則等待Promise的result產生 後返回

 1 function test8(){
 2          return new Promise(function(resolve, reject){
 3             resolve('成功返回'); //如果沒有then語句  result='成功返回';  
 4          }).then(function(r){
 5             return '這裡優先作為結果'; //如果有這個返回  最終result='這裡優先作為結果';
 6          });
 7       }
 8       
 9       async function test8_(){
10          let z= await test8(); //如果 始終不呼叫 resolve 這裡將會一直等待下去 直到獲得result
11          console.log(z);
12          console.log('end...');
13       }
14       
15       test8_();

總結await ,async 和Promise 的關係 :

1. await 必須在 async修飾的函式中呼叫

2. async 修飾的函式會把結果包裝成Promise

3. await 等待的如果不是Promise 和普通呼叫無異

4.await 會一直等待Promise 的result 出現 並返回result

最後上全部的測試程式碼:

  1 <html>
  2   <head>
  3   <title>Promise/async/await 理解</title>
  4   </head>
  5   <body>
  6      <script type='text/javascript'>
  7      new Promise(function(resolve, reject){
  8          console.log('new 完後馬上執行這個函式哦');
  9      });
 10      
 11      function test1(){
 12         return new Promise(function(resolve, reject){
 13            window.setTimeout(function(){
 14               try{
 15                 //throw '丟擲的異常222'; //這裡丟擲的異常外部promise不能 直接  catch 到哦 需內部自己捕獲後呼叫 reject 傳遞到catch
 16                 
 17                 console.log('test1.....');
 18                 resolve('ooookkkk..'); //resolve 向下一個then傳遞結果
 19               
 20               
 21               }catch(e){
 22                  reject(e); //向catch 傳遞結果
 23               }
 24               
 25            },1000);
 26            //throw '丟擲的異常111'; //這裡丟擲的異常能直接被.catch() 捕獲到哦  但是會使 setTimeout 裡面的 resolve不再呼叫了哦
 27         }).then(function(r){
 28             console.log('呼叫 resolve 後會執行我哦');
 29             console.log(r);
 30         
 31         }).catch(function(r){
 32             console.log('呼叫 reject 或throw e後 後會執行我哦');
 33             console.log(r);
 34         });
 35      }
 36      
 37     //let res1= test1(); // res1 是 Promise;
 38     //console.log(res1);
 39      
 40      
 41      
 42      function test2(n){
 43         return new Promise(function(resolve, reject){
 44            window.setTimeout(function(){
 45               console.log(n);
 46               resolve(n+100);
 47            },1000);
 48         });
 49         //.then(function(r){   
 50         //    return 99999;
 51         //});
 52      }
 53      
 54      async function test2_(){
 55         //這裡加上await 後  會等待resolve的結果n+100 或then裡面的返回  如果不呼叫resolve 會一直等待  
 56         let a= await test2(1);  
 57         console.log(a);
 58         let b=    await test2(2);
 59         console.log(b);
 60         let c=    await test2(3);
 61         console.log(c);
 62      }
 63      
 64      //test2_();
 65      
 66      
 67       async function test3_(n){ //async return 會封裝成 Promise 並把返回值 作為promise的result屬性內容\
 68         
 69         window.setTimeout(function(){
 70               console.log(n);
 71               return n+100;
 72            },1000);
 73            if (n===3){
 74               throw '異常123';
 75            }
 76            let a='返回string='+n;
 77            return a;  //實際返回Promise(result=a);
 78      }
 79      
 80      async function test3(){
 81         let a= await test3_(1);  //這裡的返回值是 函式的實際return 返回值 並不會等待裡面的setTimeout完成
 82         console.log(a);
 83         let b=     test3_(2); //這裡是 Promise 封裝 裡面封裝了 return 返回值 作為result欄位
 84         console.log(b);
 85         let c=      test3_(3).catch(function(r){console.log(r);});
 86         console.log(c);
 87         
 88         let d=new Promise(function(a,b){
 89            console.log('這樣也可以直接執行哦');
 90            return 'oookkkk'; //這裡的返回意義不大
 91         }).then(function(r){
 92            console.log('成功了會執行我哦');
 93         });
 94         
 95         console.log(d);
 96      }
 97      //test3();
 98      
 99      
100      function test4(n){
101           return new Promise(function(a, b){
102              window.setTimeout(function(){
103                 a(n+1000);
104              },2000);
105           });
106      }
107      
108      async function test4_(n){ 
109         let aa= await test4(n);
110         console.log(aa);
111         return aa; 
112      }
113      
114      async function test4___(){
115          let a=test4_(1);//這種呼叫方式不等待函式內部的非同步結果 //返回Promise(result=aa);  如果await呼叫 則返回aa
116          console.log(a);
117          console.log('test4____');
118          let b=await test4_(2);//這種呼叫等待函式內部的具體結果aa
119      }
120      //test4___();
121      
122      
123       function test5(){
124          
125          console.log('111111');
126          window.setTimeout(function(){
127             console.log('222222');
128          },1000);
129          return 33333;
130       }
131       async function test5_(){
132           let a=await test5(); //這個時候和普通呼叫無異 因為沒有返回Promise物件
133           console.log(a);
134       }
135       //test5_();
136       
137       
138       function test6(){
139         
140       }
141       function test7(){
142          //let z=await test6();//這種寫法是錯誤的  因為test6沒有返回Promise物件
143       }
144       
145       
146       function test8(){
147          return new Promise(function(resolve, reject){
148             resolve('成功返回'); //如果沒有then語句  result='成功返回';  
149          }).then(function(r){
150             return '這裡優先作為結果'; //如果有這個返回  最終result='這裡優先作為結果';
151          });
152       }
153       
154       async function test8_(){
155          let z= await test8(); //如果 始終不呼叫 resolve 這裡將會一直等待下去 直到獲得result
156          console.log(z);
157          console.log('end...');
158       }
159       
160       test8_();
161       
162      </script>
163   </body>
164 </html>

相關文章