• Promise同时获取n个接口数据的几种方式


    先使用Promise封装, 以便使用它的链式调用方法:

    const url1 = './data1.json'

    const url2 = './data2.json'

    const url3 = './data3.json'

    1. const getData = async(url) => {
    2. return new Promise((resolve, reject)=> {
    3. axios({
    4. method: 'get',
    5. url,
    6. data: {},
    7. })
    8. .then(res=> {
    9. resolve(res)
    10. })
    11. .catch(err=> {
    12. reject(err)
    13. })
    14. })
    15. }

    1.链式调用:

    1. getData(url1)
    2. .then(data1 => {
    3. console.log(data1)
    4. return getData(url2)
    5. })
    6. .then(data2 => {
    7. console.log(data2)
    8. return getData(url3)
    9. })
    10. .then(data3 => {
    11. console.log(data3)
    12. })
    13. .catch(err => console.log(err));

    2. asyc await

    1. const data1 = await getData(url1)
    2. const data2 = await getData(url2)
    3. const data3 = await getData(url3)
    4. console.log(data1, data2, data3)

    3.Promise.allSettled

    mock数据, 想要成功的数据可以Promise.resolve({a: 1}), mock失败的返回数据: Promise.reject({err1: 1})

    1. const f1 = getData(url1)
    2. const f2 = Promise.reject({err2: 2})
    3. const f3 = Promise.reject({err3: 3})
    4. Promise.allSettled([f1, f2, f3])
    5. .then(res => {
    6. // 成功和失败的数据都会返回, 可以根据需要筛选需要的数据
    7. console.log(res, 'allSettled-success')
    8. })
    9. .catch(err => {
    10. // catch没有catch到接口返回的错误数据, 全部都返回到then去了
    11. console.log(err, 'error')
    12. })
    13. .finally(() => {
    14. // 不管成功还是失败都会走到finally
    15. console.log('finally')
    16. })

    4.Promise.all

    1. Promise.all([f1, f2, f3])
    2. .then(res => {
    3. // 全部都是返回成功的数据才会打印
    4. console.log(res, 'all-success')
    5. })
    6. .catch(err => {
    7. // 只要有一个失败就会打印, 剩下的失败就不会打印了
    8. console.log(err, 'error')
    9. })
    10. .finally(()=> {
    11. // 不管成功还是失败都会走到finally
    12. console.log('all--finally')
    13. })

    5.Promise.race只有第一个resolve或者reject的数据返回了, 其余的不返回

    1. Promise.race([f1, f2, f3])
    2. .then(res => {
    3. // 如果第一个返回数据是resolve的, 就打印
    4. console.log(res, 'race-success')
    5. })
    6. .catch(err => {
    7. // 如果第一个返回数据reject的, 就打印
    8. console.log(err, 'race-error')
    9. })
    10. .finally(()=> {
    11. // 不管第一个返回的是成功还是失败都会走到finally
    12. console.log('race--finally')
    13. })

    6.Promise.all如果想要成功结果和失败结果一起返回,则

    1. function onReject(err) {
    2. return (err);
    3. }
    4. const f1 = () => getData(url1).catch(onReject)
    5. const f2 = () => getData(url2).catch(onReject)
    6. const f3 = () => getData(url3).catch(onReject)
    7. Promise.all([f1, f2, f3])
    8. .then(res => {
    9. console.log(res, 'all-success')
    10. })
    11. .catch(err => {
    12. console.log(err, 'error')
    13. })
    14. .finally(()=> {
    15. // 不管成功还是失败都会走到finally
    16. console.log('all--finally')
    17. })

    7.Promise和setTimeout模拟并发场景:

    1. function onReject(err) {
    2. return (err);
    3. }
    4. const f1 = () => getData(url1).catch(onReject)
    5. const f2 = () => getData(url2).catch(onReject)
    6. const f3 = () => getData(url3).catch(onReject)
    7. const f4 = ()=> getData(url4).catch(onReject)
    8. const f5 = () => getData(url5).catch(onReject)
    9. const f11 = () => getData(url11).catch(onReject)
    10. const f12 = () => getData(url12).catch(onReject)
    11. const f13 = () => getData(url13).catch(onReject)
    12. const f14 = ()=> getData(url14).catch(onReject)
    13. const f15 = () => getData(url15).catch(onReject)
    14. /**
    15. * 代码的核心思路为:
    16. 1.先初始化 promiseListLimit 个 promise 实例,将它们放到 executing 数组中
    17. 2.使用 Promise.race 等待这 promiseListLimit 个 promise 实例的执行结果
    18. 3.一旦某一个 promise 的状态发生变更,就将其从 executing 中删除,然后再执行循环生成新的 promise,放入executing 中
    19. 4.重复23两个步骤,直到所有的 promise 都被执行完
    20. 5.最后使用 Promise.all 返回所有 promise 实例的执行结果
    21. */
    22. const concurrencyPromisePool = async (
    23. promiseListLimit,
    24. promiseArr,
    25. mockTimeoutDataFn
    26. ) => {
    27. const allPromiseArr = []; // 用于存放所有的promise实例
    28. const executing = []; // 用于存放目前正在执行的promise
    29. for (let index = 0; index < promiseArr.length; index++) {
    30. const promise = promiseArr[index];
    31. const mockPromise = mockTimeoutDataFn(promise, index); // 回调函数返回的必须是promise,否则需要使用Promise.resolve进行包裹
    32. allPromiseArr.push(mockPromise);
    33. if (promiseListLimit <= promiseArr.length) {
    34. // then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除
    35. const executingItem = mockPromise.then(() =>
    36. executing.splice(executing.indexOf(executingItem), 1)
    37. );
    38. executing.push(executingItem);
    39. console.log(`并发接口数量: ${executing.length}`);
    40. if (executing.length >= promiseListLimit) {
    41. // 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更,
    42. // 状态变更后,就会执行上面then的回调,将该promise从executing中删除,
    43. // 然后再进入到下一次for循环,生成新的promise进行补充
    44. await Promise.race(executing);
    45. }
    46. }
    47. }
    48. return Promise.all(allPromiseArr);
    49. };
    50. // mock有1s延迟时间的promise, 方便查看并发的效果
    51. const timeout = (promiseFn, i) => {
    52. console.log("开始--", i);
    53. return new Promise((resolve) =>
    54. setTimeout(() => {
    55. console.log("结束--", i);
    56. return resolve(promiseFn());
    57. }, 1000)
    58. );
    59. };
    60. const getConcurrencyPromise = async () => {
    61. try {
    62. const res = await concurrencyPromisePool(
    63. 2,
    64. [f1, f2, f3, f4, f5, f11, f12, f13, f14, f15],
    65. timeout
    66. );
    67. console.log(res);
    68. } catch (error) {
    69. console.log(error, "errrrrr");
    70. }
    71. };
    72. getConcurrencyPromise();

    并发方法可以用于多种场景,比如大文件分片上传,要求并发,每次可以传多片的情形

  • 相关阅读:
    通信算法之九十六:电力通信系统-HRF多载波通信系统-物理层收发信道开发
    双指针算法
    Visual Studio C++项目的头文件搜索顺序
    基于nginx+keepalived的负载均衡、高可用web集群
    神经网络理论及应用,神经网络通俗易懂
    重读《纳瓦尔宝典》精彩语录及感悟篇(二)
    金仓数据库KingbaseES ksql工具用户指南及参考--2. Ksql快速启动
    1002 A+B for Polynomials
    多层感知机 MLP
    【C语言】初阶C语言零碎知识点(查漏补缺)
  • 原文地址:https://blog.csdn.net/qq_42750608/article/details/133222216