promise,await,async小论
Promise:
Promise为了解决异步回调地狱而生的,其解决方法就是链式调用promise.then()或promise.all();
Promise有两个参数,resolve和reject,第一个代表正确的返回处理,第二个代表异常的返回处理!
function promise1(){ let num = 0; return new Promise((resolve,reject)=>{ setTimeout(()=>{ num++; resolve(num); },3000); }); } promise1().then((num)=>{ console.log(num); });
3秒后输出结果是1。
then方法里有两个参数,第一个是resolve,第二个是reject,resolve可以返回一个promise,也可以直接返回一个data,直接返回的data会作为接下来的then里的resolve的形参传递。
function promise1(){ let num = 0; return new Promise((resolve,reject)=>{ setTimeout(()=>{ num++; resolve(num); },3000); }); } function promise2(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ num+=3; resolve(num); },3000); }); return p; } function promise3(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ num *= num; resolve(num); },3000); }); return p; } promise1().then((num)=>{ console.log(num); return promise2(num); }).then((num)=>{ console.log(num); return promise3(num); }).then((num)=>{ console.log(num); return 3; }).then((num)=>{ console.log(num); }).then((num)=>{ console.log(num); });
输出结果
第4个then直接返回第三个then返回的数字3,而最后一个num形参没有传递任何数据,故是undefined。
Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调,注意这个类似是静态方法,直接通过Promise.all关键词调用
Promise.all([promise1(),promise2(2),promise3(6)]).then((result)=>{
console.log(result);
});
结果:
用Promise.all来执行,all接收一个数组参数,里面的值最终都返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results
还有个race方法,all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。
promise的这种链式调用可以很好的解决回调地狱的问题!
async、await
这两个玩意解决异步回调简直是完美!
async只能放到函数前面,await只能出现在标有async的函数里,意思就是等待!async函数和正常的function一样使用,如果内部有await 那么可以抛出错误处理
async function timeout(){ let cc = await func(); } timeout().catch(error){ console.log(error); }
await可以使当前代码暂停执行,等到await 后的代码处理完后再继续向下执行,await后的方法返回的是Promise对象,也可以是自己定义的含有then方法的对象
function promiseAwt(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ let cnt = 0; while(num > 0){ cnt += num; num--; } resolve(cnt); },num); }); return p; } async function timeout(){ let cc = await promiseAwt(3000); console.log('道德经'); let dd = await promiseAwt(1000); console.log("天之道"); let ee = await promiseAwt(2000); console.log(`cc:${cc}\ndd:${dd}\nee:${ee}`); } timeout(); console.log("我先执行");
输出结果
如果现场试验你会发现,先输出 “我先执行” 等待3秒输出“道德经”,再等待1秒输出‘天之道’,再等待2秒输出累加的和 cc、dd、ee,程序在执行await的时候等待了!
await 最后得到的值就是promise的resolve传递过来的参数!
下面是综合测试:
function promise1(){ let num = 0; return new Promise((resolve,reject)=>{ setTimeout(()=>{ num++; resolve(num); },3000); }); } function promise2(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ num+=3; resolve(num); },3000); }); return p; } function promise3(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ num *= num; resolve(num); },3000); }); return p; } Promise.all([promise1(),promise2(2),promise3(6)]).then((result)=>{ console.log(result); }); function promiseAwt(num){ let p = new Promise((resolve,reject)=>{ setTimeout(()=>{ let cnt = 0; while(num > 0){ cnt += num; num--; } resolve(cnt); },num); }); return p; } async function timeout(){ let cc = await promiseAwt(3000); console.log('道德经'); let dd = await promiseAwt(1000); console.log("天之道"); let ee = await promiseAwt(2000); console.log(`cc:${cc}\ndd:${dd}\nee:${ee}`); promise1().then((num)=>{ console.log("sssss:"+num); return promise2(num); }).then((num)=>{ console.log("nnnn:"+num); return promise3(num); }).then((num)=>{ console.log("hello world----"+num); }); } timeout(); console.log("我先执行");
输出结果