场景一
函数 fn1, fn2, fn3
问题 fn3的执行需要用到fn1与fn2中接口返回的数据
方法:
async function fn() {
const response1 = await fn1();
const response2 = await fn2();
fn3(response1, responsee2);
}
场景二
函数 fn1, fn2, fn3
问题 fn3的执行需要用到fn1与fn2中接口返回的数据, 但是场景一中, fn2的执行需要等fn1执行完后才能执行, 如果fn1与fn2的接口请求时间都太长,如果实现呢?
方法:
function fn11() {
return new Promise((reslove, reject) => {
// 接口返回成功后调用reslove()
fn1(); // 模拟接口
reslove();
})
}
function fn22() {
return new Promise((reslove, reject) => {
// 接口返回成功后调用reslove()
fn2(); // 模拟接口
reslove();
})
}
function fn() {
Promise.all([fn11(), fn22()]).then(() => {
fn3();
})
}
这时函数fn11与函数fn22是异步调用的。两个接口的调用是互补影响的。
注意:如果all中参数Promise有自己的catch处理方法,就不会进入all方法中catch逻辑中,因为参数Promise处理了异常信息,相当于 reslove(),所以会进入all方法中then逻辑中。
以上两种场景,主要是对async/await与Promise的理解与运用,使异步函数同步化。
在vue中使用
第一种,生命周期加 async 通常在mounted和created这两个生命周期中
methods: {
promise1() {
return new Promise(resolve => {
resolve(1)
});
},
promise2(value) {
return new Promise(resolve => {
resolve(value)
});
}
},
async created() {
let res1 = await this.promise1();
let res2 = await this.promise2(res1);
console.log(`res2 => ${res2}`);
},
async mounted() {
let res1 = await this.promise1();
let res2 = await this.promise2(res1);
console.log(`res2 => ${res2}`);
}
第二种 在方法上加 async
methods: {
promise1() {
return new Promise(resolve => {
resolve(1)
});
},
promise2(value) {
return new Promise(resolve => {
resolve(value)
});
},
async promise3() {
let res1 = await this.promise1();
let res2 = await this.promise2(res1);
console.log(`res2 => ${res2}`);
}
},
created() {
this.promise3();
},
mounted() {
this.promise3();
}
Promise 中方法
1、all 常用于所有Promise实例都成功,只要有一个reject,就走catch,不管其他Promise是否成功。
methods: {
promise1() {
return new Promise(resolve => {
resolve(1)
});
},
promise2() {
return new Promise(resolve => {
resolve(2)
});
},
},
mounted() {
Promise.all([this.promise1(), this.promise2()]).then(res => {
console.log(res); // 返回的是参数then的集合 [1, 2]
}).catch(err => {
console.log(err); // 返回失败的哪一个Promise的reject
})
}
2、race 用于那个Promise操作快,因为只要有一个Promise实例状态改变了,无论是成功还是失败,都会触发。
methods: {
promise1() {
return new Promise(resolve => {
resolve(1)
});
},
promise2() {
return new Promise(resolve => {
resolve(2)
});
},
},
mounted() {
Promise.race([this.promise1(), this.promise2()]).then(res => {
console.log(res); // 返回的是最早执行成功的那个then 1
}).catch(err => {
console.log(err); // 遇到失败就返回
})
}
3、allSettled 所有Promise实例的状态都改变才会触发。
methods: {
promise1() {
return new Promise((resolve, reject) => {
reject('err1');
resolve(1)
});
},
promise2() {
return new Promise((resolve) => {
resolve(2)
});
},
},
mounted() {
Promise.allSettled([this.promise1(), this.promise2()]).then(res => {
console.log(res); // 返回的是所有Promise执行的状态结果 0
/**
[
{status: 'rejected', reason: 'err1'},
{status: 'fulfilled', value: 2}
]
*/
});
}
4、any 只要有一个成功返回
methods: {
promise1() {
return new Promise((resolve, reject) => {
reject('err1');
resolve(1)
});
},
promise2() {
return new Promise((resolve, reject) => {
reject('err1');
resolve(2)
});
},
},
mounted() {
Promise.any([this.promise1(), this.promise2()]).then(res => {
console.log(res); // 返回的是最早执行成功的那个then 1
}).catch(err => {
console.log(err); // AggregateError: All promises were rejected
})
}
5、如果不知道当前函数是同步函数还是异步函数,可以用Promise.try
Promise.try(() => 函数)。then().catch()
// 这样不管同步函数还是异步函数都可以获取到异常,
// catch只会捕获异步函数抛出的异常