Promise可以用来构建调用链,避免不断嵌套写回调函数
let p=new Promise((resolve,reject)=>{
console.log('a');
resolve('a');//resolve把状态改成成功,此函数结束后会按顺序调用p的所有then的第一个函数;reject将调用then的第二个函数并且会执行catch
});
let p2=p.then((a)=>{//
console.log(a+'2');
throw 'exception happend';
return 'a3';//then有返回值时,会将其封装成新的Promise,且其状态为成功
/*
等价于:
new Promise(()=>resolve('a3'));
*/
});
let p3=p2.then(p2=>console.log(p2));//用then返回的Promise再写then,构成调用链
let p4=p3.catch(a=>console.log(a));//在调用链的最后一层写catch,调用链的任何一层抛出异常或reject了会统一执行这里,实现异常统一处理
p4.finally(()=>{console.log('fin')});//如果要在某个链路中断执行,需返回一个pending状态的promise或抛出异常
console.log('other task');//在执行Promise调用链时then方法是异步执行的,即执行完调用链的头后会并发执行then方法和后面的代码
//执行调用链是按顺序同步执行的,异步是指在执行调用链的同时会去执行主线程后面的代码
//基于此特性可以用Promise实现异步编程
由于Promise是异步的,但有时我们不希望程序异步,于是诞生了async、await关键字。async用于声明方法是异步的,说明为async的方法将返回Promise,如果返回的是字符串或没有返回值将自动封装一个Promise。async方法实现异步本质上需要靠Promise来实现。我们的方法中用了Promise时那肯定就是异步的,await只能用于异步方法中,将等待Promise执行链执行完成后才往下执行
function test(){
let p=new Promise((resolve,reject)=>{
console.log('a');
resolve('a');//resolve把状态改成成功,此函数结束后会按顺序调用p的所有then的第一个函数;reject将调用then的第二个函数
});
p.then((a)=>{//
console.log(a+'2');
}).catch(a=>console.log(a));
p.then(p2=>console.log('a'+3)).catch(a=>console.log(a));//用then返回的Promise再写then,构成调用链
p.finally(()=>{console.log('fin')});//如果要在某个链路中断执行,需返回一个pending状态的promise
}
async function main() {
await test();//让多个异步方法同步执行
await test();
console.log('other task');
}
main()
用axios、Promise、async、await发送处理api请求:
axios是异步调用api,返回的是Promise对象,所以可以用then()处理调用成功,用catch()处理调用失败。可以自定义调用api的处理链。
场景一:异步调用多个api
import axios from 'axios'
export default {
name: 'HelloWorld',
props: {
msg: String
},
created(){
this.repeatLogin();
},
methods:{
sendLoginReq(times,pwd){
console.log(`${times}开始发送api请求`);
return axios.get({
url:'http://localhost:8080/login',
data: {
username:'admin',
password:pwd
},
methods: 'post'
}).then(()=>console.log(`${times}响应成功`));
},
repeatLogin(){
//并发调用api
this.sendLoginReq(1,'1233').then(/**todo:处理响应结果 */).catch(/**todo:处理调用失败 */);
this.sendLoginReq(2,'1234').then(/**todo:处理响应结果 */).catch(/**todo:处理调用失败 */);
this.sendLoginReq(3,'1235').then(/**todo:处理响应结果 */).catch(/**todo:处理调用失败 */);
this.sendLoginReq(4,'1236').then(/**todo:处理响应结果 */).catch(/**todo:处理调用失败 */);
}
}
}
场景二:同步调用多个api
import axios from 'axios'
export default {
name: 'HelloWorld',
props: {
msg: String
},
created(){
this.repeatLogin();
},
methods:{
sendLoginReq(times,pwd){
console.log(`${times}开始发送api请求`);
return axios.get({
url:'http://localhost:8080/login',
data: {
username:'admin',
password:pwd
},
methods: 'post'
}).then(()=>console.log(`${times}响应成功`));
},
async repeatLogin(){
try {
//使用await把异步发送api请求变成同步。
await this.sendLoginReq(1,'1233').then(/**todo:处理响应结果 */).catch(e=>{throw e});
await this.sendLoginReq(2,'1234').then(/**todo:处理响应结果 */).catch(e=>{throw e});
await this.sendLoginReq(3,'1235').then(/**todo:处理响应结果 */).catch(e=>{throw e});
await this.sendLoginReq(4,'1236').then(/**todo:处理响应结果 */).catch(e=>{throw e});
} catch (error) {//统一处理异常
console.log(`错误码:${error.code},错误信息:${error.message}`)
}
}
}
}