先使用Promise封装, 以便使用它的链式调用方法:
const url1 = './data1.json'
const url2 = './data2.json'
const url3 = './data3.json'
-
- const getData = async(url) => {
- return new Promise((resolve, reject)=> {
- axios({
- method: 'get',
- url,
- data: {},
- })
- .then(res=> {
- resolve(res)
- })
- .catch(err=> {
- reject(err)
- })
- })
- }
1.链式调用:
- getData(url1)
- .then(data1 => {
- console.log(data1)
- return getData(url2)
- })
- .then(data2 => {
- console.log(data2)
- return getData(url3)
- })
- .then(data3 => {
- console.log(data3)
- })
- .catch(err => console.log(err));
2. asyc await
- const data1 = await getData(url1)
- const data2 = await getData(url2)
- const data3 = await getData(url3)
-
- console.log(data1, data2, data3)
3.Promise.allSettled
mock数据, 想要成功的数据可以Promise.resolve({a: 1}), mock失败的返回数据: Promise.reject({err1: 1})
- const f1 = getData(url1)
- const f2 = Promise.reject({err2: 2})
- const f3 = Promise.reject({err3: 3})
- Promise.allSettled([f1, f2, f3])
- .then(res => {
- // 成功和失败的数据都会返回, 可以根据需要筛选需要的数据
- console.log(res, 'allSettled-success')
- })
- .catch(err => {
- // catch没有catch到接口返回的错误数据, 全部都返回到then去了
- console.log(err, 'error')
- })
- .finally(() => {
- // 不管成功还是失败都会走到finally
- console.log('finally')
- })
4.Promise.all
- Promise.all([f1, f2, f3])
- .then(res => {
- // 全部都是返回成功的数据才会打印
- console.log(res, 'all-success')
- })
- .catch(err => {
- // 只要有一个失败就会打印, 剩下的失败就不会打印了
- console.log(err, 'error')
- })
- .finally(()=> {
- // 不管成功还是失败都会走到finally
- console.log('all--finally')
- })
5.Promise.race只有第一个resolve或者reject的数据返回了, 其余的不返回
- Promise.race([f1, f2, f3])
- .then(res => {
- // 如果第一个返回数据是resolve的, 就打印
- console.log(res, 'race-success')
- })
- .catch(err => {
- // 如果第一个返回数据reject的, 就打印
- console.log(err, 'race-error')
- })
- .finally(()=> {
- // 不管第一个返回的是成功还是失败都会走到finally
- console.log('race--finally')
- })
6.Promise.all如果想要成功结果和失败结果一起返回,则
- function onReject(err) {
- return (err);
- }
- const f1 = () => getData(url1).catch(onReject)
- const f2 = () => getData(url2).catch(onReject)
- const f3 = () => getData(url3).catch(onReject)
-
- Promise.all([f1, f2, f3])
- .then(res => {
- console.log(res, 'all-success')
- })
- .catch(err => {
- console.log(err, 'error')
- })
- .finally(()=> {
- // 不管成功还是失败都会走到finally
- console.log('all--finally')
- })
7.Promise和setTimeout模拟并发场景:
- function onReject(err) {
- return (err);
- }
-
- const f1 = () => getData(url1).catch(onReject)
- const f2 = () => getData(url2).catch(onReject)
- const f3 = () => getData(url3).catch(onReject)
- const f4 = ()=> getData(url4).catch(onReject)
- const f5 = () => getData(url5).catch(onReject)
- const f11 = () => getData(url11).catch(onReject)
- const f12 = () => getData(url12).catch(onReject)
- const f13 = () => getData(url13).catch(onReject)
- const f14 = ()=> getData(url14).catch(onReject)
- const f15 = () => getData(url15).catch(onReject)
-
-
- /**
- * 代码的核心思路为:
- 1.先初始化 promiseListLimit 个 promise 实例,将它们放到 executing 数组中
- 2.使用 Promise.race 等待这 promiseListLimit 个 promise 实例的执行结果
- 3.一旦某一个 promise 的状态发生变更,就将其从 executing 中删除,然后再执行循环生成新的 promise,放入executing 中
- 4.重复2、3两个步骤,直到所有的 promise 都被执行完
- 5.最后使用 Promise.all 返回所有 promise 实例的执行结果
- */
- const concurrencyPromisePool = async (
- promiseListLimit,
- promiseArr,
- mockTimeoutDataFn
- ) => {
- const allPromiseArr = []; // 用于存放所有的promise实例
- const executing = []; // 用于存放目前正在执行的promise
- for (let index = 0; index < promiseArr.length; index++) {
- const promise = promiseArr[index];
- const mockPromise = mockTimeoutDataFn(promise, index); // 回调函数返回的必须是promise,否则需要使用Promise.resolve进行包裹
- allPromiseArr.push(mockPromise);
- if (promiseListLimit <= promiseArr.length) {
- // then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除
- const executingItem = mockPromise.then(() =>
- executing.splice(executing.indexOf(executingItem), 1)
- );
- executing.push(executingItem);
- console.log(`并发接口数量: ${executing.length}`);
- if (executing.length >= promiseListLimit) {
- // 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更,
- // 状态变更后,就会执行上面then的回调,将该promise从executing中删除,
- // 然后再进入到下一次for循环,生成新的promise进行补充
- await Promise.race(executing);
- }
- }
- }
- return Promise.all(allPromiseArr);
- };
-
- // mock有1s延迟时间的promise, 方便查看并发的效果
- const timeout = (promiseFn, i) => {
- console.log("开始--", i);
- return new Promise((resolve) =>
- setTimeout(() => {
- console.log("结束--", i);
- return resolve(promiseFn());
- }, 1000)
- );
- };
-
- const getConcurrencyPromise = async () => {
- try {
- const res = await concurrencyPromisePool(
- 2,
- [f1, f2, f3, f4, f5, f11, f12, f13, f14, f15],
- timeout
- );
- console.log(res);
- } catch (error) {
- console.log(error, "errrrrr");
- }
- };
-
- getConcurrencyPromise();
并发方法可以用于多种场景,比如大文件分片上传,要求并发,每次可以传多片的情形