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>